SSH for novices – brief introduction

Allways use SSH when connecting to remote hosts!
Allways use SSH when connecting to remote hosts!
За повечето от интернет потребителите SSH е нещо като наследник на FTP или е известно като „онова с което се качват файловете“ което е ГРУБА грешка. Всъщност корените на SSH датират от telnet и неговата липса на всякаква липса на шифриране. ФАКТ е, че първоначално на сигурността не се е гледало сериозно в telnet/rsh/rlogin паролите и изобщо цялата информация тече некриптирана. Млад изследовател се е заел да отстрани тази несправедливост и се е появил SSH като напълно нов протокол създаден да замести изцяло telnet и събратята му. SSH не само замества telnet, но и се превръща в доминиращ протокол в интернет за отдалечен достъп. Към настоящия момент SSH се разработва активно от SSH, но съществуват няколко версии с отворен код като най-известните са OpenSSH и dropbear.

Това което е уникалното е, че благодарение на SSH са се появили цял набор от услуги които работят върху него:
– файловия трансфер за който споменах в началото
– тунелизиране или пренасочване на портове
– проксифирицане на връзката със SOCKS прокси
– изграждане на архиви или огледала със rsync
– пренасочване на X
– и други

Сега ще ви покажа как го използвам в ежедневните си нужди в 2 варианта. Имам една машина намираща се зад по-сложна огнена стена и не мога да я достъпвам отдалечено лесно през GUI. Машината има отворен един единствен порт 22 (SSH) към нея от огнената стена. На същата машина има стартиран vnc server на порт 5900 както и разни други интересни услуги до които обаче нямам никакъв достъп. Затова отварям терминал и пиша заветната команда:
ssh -L 5999:127.0.0.1:5900 -N username@my.server.com
натискам enter, пиша си паролата и ако всичко е наред ще бъде стартирано пренасочването, отварям нов терминал и си влизам във vnc-то по следния начин:
open vnc://localhost:5999
Сега какво правят горните две команди – първата стартира пренасочване от локален порт 5999 към отдалечена машина 127.0.0.1 на порт 5900 (което е порта на vnc). Със -N инструктирам SSH да не стартира команден промпт и само да пренасочи портовете. Когато VNC сесията ми приключва излизам от VNC клиента, връщам се в конзоната където SSH е стартиран и натискам ctrl-c. Разбира се SSH се оплаква по следния начин:
^CKilled by signal 2.
което е сигнал че връзката към отдалечената машина е затворена. Порт 5999 вече не е отворен и пренасочването вече не работи.

Вторият сценарий е малко по-странен. Болшинството от потребителите не знаят, но под SSH е възможно да се стартира локален socks сървър който ще пренасочва всичко към отдалечения сървър. Разбира се не се изисква нещо супер сложно. Напълно достатъчно е да се напишa следната комбинация в терминала:
ssh -D 1080 -N username@my.server.com
натискам enter с което socks проксито е стартирано. След което си стартирам приложението което отчаяно се нуждае от прокси (в дадения случай Firefox), набивам в опциите че имам socks прокси с параметри 127.0.0.1:1080 и готово. Ако се налага порта да бъде отворен мрежово т.е. да бъде наличен и за други машини в локалната мрежа, а не само за локалната машина нейде в параметрите е необходимо да се напише просто едно -g след ssh. Разбира се това е една МНОГО малка част от възможностите на SSH. Например е възможно да се отвори пренасочи порт от сървъра към локалната машина (подобно на -L, но се пише -R), възможно е използването на отдалечена файлова система (SSHFS) и много други.

Може би по-голяма част от вас ще използват SSH под Windows с използването на putty. В момента уви не разполагам със Windows, но скоро ще публикувам как по-горните примери може да се използват и под Windows.

SSH for novices – brief introduction

Cheating Blitz comment voting

Наближават избори, а живеем в 2013 година така, че очаквано днешната политагитация се води по форуми, социални мрежи и всякакви сайтове.

Направи ми впечатление как в Blitz.bg понякога оценките за коментарите се развиват за секунди и чуждото мнение се потапя с много на брой отрицателни гласове, а „правилното“ се подкрепя.

Седнах и намерих една статия с която да експериментирам за целта – http://www.blitz.bg/article/33765 и един безобиден коментар от нея

Ето и избрания коментар за целта.
Ето и избрания коментар за целта.

След което отваряме конзола и пишем заветния ред:
curl --data "vote=1&tag=show&id=143698" "http://www.blitz.bg/libs/commentsajax.php?vote=1&tag=show&id=143698"

Ето и резултата от няколко извиквания на реда:

curl --data "vote=1&tag=show&id=143698" "http://www.blitz.bg/libs/commentsajax.php?vote=1&tag=show&id=143698"
<span class=\"ocenka\">Оценка<br />-0 <span>+16</span></span>
curl --data "vote=1&tag=show&id=143698" "http://www.blitz.bg/libs/commentsajax.php?vote=1&tag=show&id=143698"
<span class=\"ocenka\">Оценка<br />-0 <span>+17</span></span>
curl --data "vote=1&tag=show&id=143698" "http://www.blitz.bg/libs/commentsajax.php?vote=1&tag=show&id=143698"
<span class=\"ocenka\">Оценка<br />-0 <span>+18</span></span>
curl --data "vote=1&tag=show&id=143698" "http://www.blitz.bg/libs/commentsajax.php?vote=1&tag=show&id=143698"
<span class=\"ocenka\">Оценка<br />-0 <span>+19</span></span>
curl --data "vote=1&tag=show&id=143698" "http://www.blitz.bg/libs/commentsajax.php?vote=1&tag=show&id=143698"
<span class=\"ocenka\">Оценка<br />-0 <span>+20</span></span>

Изглежда оценките може да се манипулират. Забелязах същото в сайтовете на 24Часа, Дир, Дневник, Капитал и още много други. Но няма да ви помагам със скриптове за тях.
Затова когато видите мнения с много плюсове или минуси имайте едно на ум, че е възможно да са манипулирани.

Cheating Blitz comment voting

Autopost to Svejo.net

Ако преди седмица ви показах как можете да публикувате във Facebook то днес ще ви покажа как можете да го направите във Svejo.net

Svejo add url to site
Svejo add url to site


<?PHP
/*******************************
* Svejo Status Updater
* Peter Nikolow
* http://peter.nikolow.me
* March 29, 2013
*******************************/

$login_email = 'type-here-your-mail';
$login_pass = 'type-here-your-password';
$url_4submit = 'type-here-your-url';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://svejo.net/user/login');
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEJAR, "my_cookies.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE, "my_cookies.txt");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; Linux 2.6.22) NetFront/3.4 Kindle/2.0 (screen 600x800)");
$loginpage = curl_exec($ch);

curl_setopt($ch, CURLOPT_POST, 1);
preg_match("/input name=\"authenticity_token\" type=\"hidden\" value=\"(.*?)\"/", $loginpage, $form_authtoken);
curl_setopt($ch, CURLOPT_POSTFIELDS,'authenticity_token='.urlencode($form_authtoken[1]).'&user%5Bemail_or_username%5D='.urlencode($login_email).'&user%5Burl_referer%5D=http%3A%2F%2Fsvejo.net%2F&user%5Bremember_me%5D=0&user%5Bpassword%5D='.urlencode($login_pass).'&commut=%D0%92%D0%BB%D0%B5%D0%B7');
$loginpage = curl_exec($ch);

sleep(10);
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_URL, 'http://svejo.net/publish/');
$page = curl_exec($ch);

sleep(10);
curl_setopt($ch, CURLOPT_POST, 1);
preg_match("/input name=\"authenticity_token\" type=\"hidden\" value=\"(.*?)\"/", $page, $form_authtoken);
$formvars = array();
$formvars['authenticity_token'] = $form_authtoken[1];
$formvars['story[url]'] = $url_4submit;
$formvars['commit'] = "Добави";
curl_setopt($ch, CURLOPT_POSTFIELDS, $formvars);
curl_setopt($ch, CURLOPT_URL, 'http://svejo.net/publish/submit');
$page2 = curl_exec($ch);

curl_close($ch);
?>

А сега малко разшифровка на горния код.

  1. Трябва да се заредим страницата http://svejo.net/user/login
  2. От горната страница вземаме изключително важния параметър authenticity_token който го подаваме заедно с името/паролата към същата страница
  3. Зареждаме тази страница http://svejo.net/publish/ с цел вземането на authenticity_token
  4. Извършваме POST към http://svejo.net/publish/submit като подаваме token-a и URL-a които трябва да бъдат предадени

За всеки случай сме прибавили едно временно заспиване от 10 секунди между заявките за да не може системата да ни разпознае като ботове, каквито всъщност сме. Средно дневно в системата се прибавят около 2100 линка (информацията е от 30 Март 2013 година) което прави 87,5 линка на час. Или приблизително 2,5 линка на минута. Ако горния код се модифицира също като предходния би могъл денонощно да публикува всякакви линкове независимо от времето,но не е това целта на упражнението. Задачата е приключена и вече имаме скрипт за автоматично публикуване във Svejo.net

Autopost to Svejo.net

Autopost to Facebook

От известно време ме тормози идеята за автоматично обновяване (autopost) на статуса във Facebook и други социални мрежи без други системи и приложения. Затова взех задачата присърце, седнах и преправих един прост скрипт който да свърши черната работа.

Facebook status update
Facebook status update


<?PHP
/*******************************
* Facebook Status Updater version 0.1
* Peter Nikolow
* http://peter.nikolow.me
* March 22, 2013
*******************************/

function random_string( )
{
$character_set_array = array( );
$character_set_array[ ] = array( 'count' => 7, 'characters' => 'abcdefghijklmnopqrstuvwxyz' );
$character_set_array[ ] = array( 'count' => 1, 'characters' => '0123456789' );
$temp_array = array( );
foreach ( $character_set_array as $character_set )
{
for ( $i = 0; $i < $character_set[ 'count' ]; $i++ ) { $temp_array[ ] = $character_set[ 'characters' ][ rand( 0, strlen( $character_set[ 'characters' ] ) - 1 ) ]; } } shuffle( $temp_array ); return implode( '', $temp_array ); } $status = random_string(10); $login_email = 'type-here-your-mail'; $login_pass = 'type-here-your-pass'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://m.facebook.com/login.php?refsrc=http%3A%2F%2Fwww.facebook.com%2Flogin.php&refid=9'); curl_setopt($ch, CURLOPT_POSTFIELDS,'email='.urlencode($login_email).'&pass='.urlencode($login_pass).'&login=Login'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_COOKIEJAR, "my_cookies.txt"); curl_setopt($ch, CURLOPT_COOKIEFILE, "my_cookies.txt"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; Linux 2.6.22) NetFront/3.4 Kindle/2.0 (screen 600x800)"); $loginpage = curl_exec($ch); curl_setopt($ch, CURLOPT_POST, 0); curl_setopt($ch, CURLOPT_URL, 'http://m.facebook.com/home.php'); $page = curl_exec($ch); curl_setopt($ch, CURLOPT_POST, 1); preg_match("/input type=\"hidden\" name=\"fb_dtsg\" value=\"(.*?)\"/", $page, $form_id); preg_match("/form method=\"post\" id=\"composer_form\" action=\"(.*?)\"/", $page, $form_num); curl_setopt($ch, CURLOPT_POSTFIELDS, 'fb_dtsg=' . $form_id[1] . '&privacy=&charset_test=%E2%82%AC%2C%C2%B4%2C%E2%82%AC%2C%C2%B4%2C%E6%B0%B4%2C%D0%94%2C%D0%84&target=&status=' . urlencode($status) . '&update=' . urlencode("Share")); curl_setopt($ch, CURLOPT_URL, 'http://m.facebook.com' . $form_num[1]); $page2 = curl_exec($ch); curl_close($ch); ?>

Скрипта е сравнително глупав, но ще ви го обясня накратко:

  1. Генерира се случаен стринг от 10 символа който ще бъде нашия нов статус. Това е много важно защото FB блокира показването на еднакви статуси и ми коства няколко часа докато го проумея. С това се избягва блокирането на статуса и е винаги уникален.
  2. До първия curl_exec се изпълнява логване във Facebook с указаното потребителско име и парола. За да се избегне тежкия desktop ajax се представяме като много прост мобилен браузър. Така избягваме получаването на iOS/Android ajax версия която също е по-тежка за обработка. Кукитата се запазват във външен файл с цел последващо използване.
  3. Със втория curl_exec се насочваме към основната страница на Facebook където ще обновим статуса на потребителя.
  4. До третия curl_exec се изпълнява основната функция на обновяването. Проблема е че FB използва динамични форми и първо трябва да обработим втория резултат като вземем изключително важните параметри fb_dtsg - уникално id за формата и composer_form - сочещ към url-a който трябва да бъде извикан с третата заявка. Така композираме третата заявка която обновява статуса с няколко фиксирани параметъра.
  5. Последния ред затваряме curl и задачата е приключена. Можем да изтрием файла с cookies защото вече не е необходим.

С което задачата е изпълнена с няколко особенности:

  • Скрипта има проблеми с кирилицата! За момента не може да се публикува статус без да се счупи кирилицата. Тук проблема е по-тежък защото самия FB кара браузъра със специфично HTML поле "charset_test" да върне какво поддържа като езици и подозирам че нещо и оттам обърква кирилицата.
  • Скрипта се представя за мобилен агент което води до показването на "from mobile" под поста.
  • За момента показването на линкове не е много ефективно.
  • Не могат да се качват снимки във timeline.
  • Липсва проверка дали предходните операции са се случили безпроблемно. Например ако потребителското име/паролата са грешни не се спира изпълнението както и не се проверява дали обновяването на статуса минава безпроблемно.
  • Не може да се контролира видимоста на поста (Public/Friends/Me). Мисля че се използва настройката на потребителя.
  • Публикуването е фиксирано от името на човека и не може да се публикува от страница. Засега...

Надявам се със следващите версии да подобря част от недъзите на съществуващия скрипт. Системата е много гъвкава и на тази база може сравнително лесно да се направи подобен скрипт за публикуване във Twitter, Linkedin, Sharetronix, StatusNet и други подобни системи. Малко по-сложно ще е публикуването в Google+, но принципа е същия както в горните системи и не виждам причина да не бъде налична и тази социална мрежа.
С горния скрипт може да се направят много неща - примерно може да се настрои сървър да отчита параметрите си в интернет, може да се настрои автоматично постване през час от база данни, може да се извърши постване от името на потребител за вирална реклама и т.н. Общо взето възможностите са неограничени с тънкия момент, че не е много по правилата на Facebook. Ако трябва да бъде по правилата трябва да бъде приложение което потребителя с OAuth да упълномощи да извърши няколко дейности включително промяна на статуса.
За моя радост използвам скрипта САМО за лично ползване и то не и под основния ми акаунт. Ако имате въпроси ще бъда радостен да ви отговоря.

Autopost to Facebook

iphone png revert

По време на компилацията с XCode на приложения се извършват и доста други странични дейности. Например plist файловете стават binary plist, PNG файловете се оптимизират и още други такива (не са предмет на разглеждане в момента).

Ако plist файловете може все пак да се обърнат обратно с помоща на командата plutil, това не е фатално защото всички редактори отварят и двата формата (XML/Binary). За PNG файловете обаче е фатално защото вече получения файл може да бъде задеден само на iOS и на нищо друго. Всички опити за отварянето на вече преобразуван файл под какъвто и да е инструмент пропада. Или дава грешка или файла се отваря, но с бял цвят. До вчера живях с илюзията, че процеса е необратим БЕЗ използване на външни програми специално създадени за целта. За моя радост обаче днес разбрах, че процеса е напълно обратим (с помоща на XCode!)! За целта трябва да се използва следната команда в терминала:

/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/pngcrush
-revert-iphone-optimizations -q OptimizedPNG.png RevertedPNG.png

Това ще позволи файла OptimizedPNG.png да се върне в изходно състояние като RevertedPNG.png

Разбира се не съм чак толкова голям гений, ами го прочетох оттук:
http://iphonedevelopertips.com/xcode/undo-xcode-png-optimizations-using-pngcrush.html

iphone png revert

compiling libpng as universal binary for Mac OSX

Човек дори и добре да живее все някога опира до компилации на проекти с отворен код с цел последващо вграждане. Преди няколко дена ми се наложи да компилирам и libpng за да го вградя като статична библиотека в проект. Понеже проекта е universal binary (i386 и x86_64) ми трябва обаче и библиотеката да поддържа и двете архитектури. Компилация само за x86_64 или i386 не ми вършеше работа.
Затова се разтърсих и намерих следния скрипт:

./configure CFLAGS=“-arch i386 -arch ppc“ CXXFLAGS=“-arch i386 -arch ppc“ –disable-dependency-tracking

Понеже на мен ppc не ми трябваше просто го замених с x86_64 и скрипта изглеждаше така:

./configure CFLAGS=“-arch i386 -arch x86_64″ CXXFLAGS=“-arch i386 -arch x86_64″ –disable-dependency-tracking

После правим един бърз make и резултатния файл се намира тук .libs/libpng12.a За всеки случай пишем:

$lipo -info .libs/libpng.a
Architectures in the fat file: .libs/libpng.a are: i386 x86_64

И резултата е че имаме универсална библиотека с поддръжка на i386 и x86_64!
compiling libpng as universal binary for Mac OSX

Kindle Fire root 6.2.2

След като в предния пост ви показах как се премахва защитата на самите книги сега ще ви покажа и как можете да придобиете пълен контрол върху Kindle посредством техника известна като rooting.

Понеже Amazon са „лоши“ обновленията към самото устройство са OTA (Over The Air т.е. безжично) и не подлежат на спиране.  Няма вариант в който устройството ще остане на по-стара версия без ръчни корекции.

И така сега ще ви покажа как можете да си root-нете Kindle който вече е вдигнат към 6.2.2. Техниката е успешно изпробвана от мен и работи. За съжаление пиша това на OSX и нямам идея как би могло да стане под Windows или Linux.

Ето и конкретните стъпки за целта:

  1. Активирайте в менюто Menu->Settings->Applications->Development секцията USB Debugging. Отделно в Menu->Settings->Applicaitons активирайте Unknown Sources.
  2. Това е най-важната стъпка, но се изпълнява само един път. Тъй като Kindle Fire е създаден с Android всички помошни средства трябва да го виждат. Но за съжаление не е така. Затова ние трябва да добавим един ред в следния файл: ~/.android/adb_usb.ini
    Отваряме този файл и добавяме следния ред:
    0x1949
    Този ред ще укаже на adb (Android Debug Bridge) ако види устройство с подобен идентификатор да го третира като Android. В противен случай връзката на Fire с OSX няма да го покаже като устройство което може да бъде контролирано.
  3. Отваряме терминал и пишем следното:
    adb push BurritoRoot2.bin /data/local/
    adb shell chmod 777 /data/local/BurritoRoot2.bin
    adb shell /data/local/BurritoRoot2.bin
    adb root
    adb shell id
  4. Сега е критичния момент ако shell id не върне че uid=0 то трябва да изпълним стъпка 3 наново. Понякога се получава от първия път, друг път се налага няколко пъти да се изпълни стъпката.
  5. Изпълняваме следните команди:
    adb remount
    adb push su /system/xbin/su
    adb shell chown 0.0 /system/xbin/su
    adb shell chmod 06755 /system/xbin/su
    adb remount
    adb install Superuser.apk
  6. Ако всичко е готово то тогава в секцията Apps трябва да се появи приложението Superuser след което го изпълняваме него и сме готови!

Всички файлове се намират на следните места:

  • adb е част от Android SDK и може да бъде изтеглено от самия сайт. Ако файла от точка едно ви липсва то може да се наложи да го инсталирате ИЛИ да го смъкнете от тук: KindleFireRootMacLinux
  • BurritoRoot2 може да се смъкне оттук: BurritoRoot2.bin
  • Superuser.apk може да бъде смъкнат оттук: superuser
  • su е част от пакета KindleFireRootMacLinux

Горната гимнастика от-до отнема около 5 минути след което може да се наслаждавате на отключен и работещ на 100% KindleFire. В интернет може да се намерят и обяснения как да подкарате Android 4.0 на съответното устройство, но моята цел не е това.

Kindle Fire root 6.2.2

Kindle DRM Removal

Ще напиша малко по-дълъг пост тук. Ако някой е отегчен моля да го игнорира. Ако администраторите сметнат, че е нецелесъобразно да стои да го премахнат.

И така – имаме си вече Kindle, Kindle за Mac, PC и други такива. Обаче еволюцията достига до следващото ниво – share. Приятел ни моли да му дадем книга която я имаме, или се опитваме да изкопираме част от книгата във Facebook, дипломна работа или просто да разпечатаме нещо от нея…

За съжаление удряме една голяма греда която се казва DRM (или по-известна като управление на цифровите права). Понеже Amazon се отнасят много критично към това DRM-a  e интегриран в самия файлов формат и е почти невъзможно да пуснем самата книга на друго устройство.

Но вече сме 21 век и традициите отдавна не са това което бяха – затова ние започваме да търсим умни глави (хакери) които да са направили нещо за нас. И естественно има няколко скрипта с които се смъква самата DRM защита на коя-да-е kindle книга.

Първото което намерих беше комбинация от модули за всеизвестния Calibre. Обаче се натъкнах на нова греда – не можах да ги подкарам правилно и те просто не работеха. Затова потърсих нещо много по-лесно и просто като за новак и го намерих:

http://www.ebook-converter.com/kindle-drm-removal.htm

Това малко чудо на хартия ми позволява да смъкна защитата, но имах нов проблем при подкарването му. Аз се опитвах да смъкна защитата на книга доставена директно от Amazon и все даваше проблем (т.е. смъкната като файл така че ръчно да я кача на самия Kindle). Докато ми хрумна гениалната идея, че може би ако си кача Kidnle for Mac смъкна книгата и подам на програмата вече качената там книга би имал по-голям успех. Така и направих и до минута вече имах първата книга като .mobi файл успешно импортирана в Calibre.

След като разбрах каква ми е била грешката се върнах към първия вариант с модулите и до 5 минути имах сглобен и напълно работоспособен Calibre въоръжен да смъква всякакви защити.

И малко забележки:
1. Продукта е ПЛАТЕН, но използва python скриптове които вършат основната работа.
2. Библиотеките за Calibre са достъпни онлайн. Даже след преглеждане се оказва че библиотеките и продукта използват общи python скриптове.
3. Продукта е платен, но изхождайки от моралната страна на нещата (използване на open source скриптове и вграждането им в комерсиално приложение) действах малко безскрупулно и го направих полу-безплатен под Mac (повече детайли само на лични, искам да се убедя че метода работи).
4. Нарушаването на интелектуалните права е наказуемо и с това се занимават всякакви закони – DMCA/SOPA/PIPA и т.н. Така че умната.

Kindle DRM Removal