יום שישי, 28 בינואר 2011

Keystroke - Between Application C#

עלתה לי מחשבה מעניינת האם ניתן לשלוח מחרוזות (Strings) לתוכניות אחרות שרצות ברקע על המחשב, כלומר לחקות את המקלדת ובעצם לשתול מחרוזות שנשלחות מאחורי הקלעים ללא התערבות המשתמש, זה בעצם כלי Brute Force קלאסי לכל מי שרוצה לבדוק אם המערכת שלו פגיעה נגד Brute Force, לצורך העניין נניח שיש לנו טופס Login בתוכנה, בעזרת הטכניקה הזו אני יכול לנסות לשלוח את השם משתמש והסיסמא ישירות לתוכנה באופן אוטומטי ובעצם להשתמש ברשימה רצה ששולפת שמות ומנסה להיכנס לתוכנה.

הרעיון שעומד מאחורי זה בעצם ה Focus של החלון, איזה חלון פעיל באותו רגע ע"י המשתמש, אם נשתמש בתוכנה שברקע עובדות תוכנות אחרות,המקלדת תגיב רק לתוכנה שאנחנו עובדים עליה, הנושא מחולק ל 2 שלבים:

  • קבלת החלונות הקיימים.
  • שליחת ה Stroke לחלון שבחרנו.

User32.dll
הספרייה שמנהלת את כל ה Interface של Windows , ובעצם אחראית על ה Desktop שלנו, דרכה נתקשר עם חלונות שברקע.

(GetWindow(int hwnd,int wcmz
אפשרות של קבלת Handler של החלונות שרצים ברקע, על מנת שנוכל לקבל את כולם, קודם נמצא את ה Handler של התוכנה שלנו בעזרת הפונקציה GetDesktopWindow ואח"כ נשתמש בקבוצה של integers שיחזירו לנו את ה Handler של החלון שאחרי ה Handler של החלון שלנו, בעצם יש לנו מערך של Handlers שמייצג את החלונות שיש לנו ב Desktop, על מנת שנוכל להינעל על החלון שאליו אנו רוצים לשלוח את ה Stroke שלנו.

GW_HWNDFIRST = 0
יחזיר לנו את ה Handler של החלון הראשון ב Desktop.

GW_HWNDLAST = 1
יחזיר לנו את ה Handler החלון האחרון ב Desktop.

GW_HWDNEXT = 2
יחזיר לנו את ה Handler הבא בתור מהחלון שלנו.

GW_HWNDPREV = 3
יחזיר לנו את ה Handler של החלון שלפני החלון שלנו.

GW_OWNER = 4
יחזיר את ה Handler של הבעלים של החלון שלנו, כלומר אם זאת תוכנה בריבוי חלונות נוכל לדעת מי החלון הראשי.

GW_CHILD = 5
יחזיר את ה Handler של הילדים בתוכנה מרובת חלונות.



()GetDesktopWindow
יחזיר לנו את ה Handler של החלון הראשי.

GetParent(int hwnd)
מחזיר חלון האב של החלון שב Handler

FindWindow(string lpClassName,string lpWindowName)
מוצא את החלון לפי ה Title שלו
 
SetForegroundWindow(int hwnd)
החלון שנבחר ע" ה Handler שלו נהיה ב Focus
   
IsWindowsVisible(int hwnd)
האם החלון ניתן לתצוגה.




שליחת ה Stroke שלנו מתבצעת דרך המחלקה System.Windows.Forms.SendKeys.

Send(string abc)
פונקציה לשליחת ה String לחלון שנמצא ב Focus לכן מתבצע התהליך למציאת החלון ולהפוך אותו לפעיל.

 SendWait(string abc)
שולח את ה String וממתין לתשובה מהחלון הפעיל.
Flush()
מחכה שהחלון שמקבל את ה String שיעבד אותו לפני ששולחים את הבא אחריו.


יש בעיה לשלוח את זה באופן רציף במיוחד ב IE שלא ממש מגיב טוב לזה, לכן יש מספר פתרונות על מנת שזה יעבוד על דפדפנים, הנקודה הראשונה היא לדאוג שירוץ Thread.Sleep בין שליחה לשליחה יש אפשרות נוספת להישתמש ב VBScript שיפעל ישירות דרך התוכנית שלנו,ניצור לנו קובץ vbs ,ונכניס לתוכו את הקוד הבא:

set WshShell = WScript.CreateObject("WScript.Shell")
WScript.Sleep 4000
WshShell.SendKeys "My first Text"
WshShell.SendKeys "{TAB}"
WshShell.SendKeys "My Second Text"

נפעיל את ה Script בעזרת System.Diagnostics
System.Diagnostics.Process.Start("C:\\sendstroke.vbs");




עכשיו נשאלת השאלה איך אני שולח מקשים מיוחדים כמו Shift ו Ctrl?
יש 2 קבוצות של מקשים, הקבוצה הראשונה היא Space,Alt,Shift,Control:
Space = ' '
Shift = '+'
Alt = '!'
Control = '#'
יש להוריד את הגרשיים כששולחים את ה Stroke.

שאר המקשים המיוחדים במקלדת מחוייבים להיות מסומנים בסוגריים מסולסלים {Enter} אחרת הם יעברו כ String רגיל כחלק מה String ששלחנו, ולא יגיבו כמקש.

רשימת מקשים:

{BS}                 {BREAK}               {CAPSLOCK}
{DEL}              {DOWN}                {END}
{ENTER}         {ESC}                     {HELP}
{HOME}          {INSERT}               {LEFT}
{NUMLOCK} {PGDW}                 {PGUP}
{PRTSC}         {RIGHT}                 {SCROLLLOCK}
{UP}                {F1} - {F12}
 
הדגמה:



יום שבת, 22 בינואר 2011

Information Gathering

לפני כל מבצע מתבצע איסוף מידע על היעד, כמו שזה במציאות כך זה גם בעולם הוירטואלי, איסוף המידע לפני התקפה הוא שלב קריטי עבור התוקף, בלעדיו לא ניתן לצאת להתקפה.

איסוף האינפורמציה מתבצע בהמון טכניקות במטרה לקדם את ההתקפה, נניח שיש 2 חברות (אחת נקרא ל A ולשניה B) והן מיצרות את אותו מוצר וכל אחת תופסת חצי מהשוק, הפלטפורמה השיווקית שלהם היא האינטרנט, ובעל הבית של חברת A התחרפן על דעתו והחליט שהוא רוצה לתפוס 80 אחוז מהשוק, הוא ניסה בדרכים ישרות וכשראה שזה בלתי אפשרי הוא הלך לצד האפל ברשת והפעיל קבוצה של אנשים מסתוריים שיעשו בשבילו את העבודה.

נניח שאנחנו היא החברה האפלה והמיסתורית, כיצד נשלים את המשימה הזדונית?
אנחנו יודעים את המטרה, אנחנו יודעים את הפלתפורמה ועכשיו נתחיל באיסוף המידע.

מי האויב שלנו?
השלב הראשון באיסוף המידע הוא להבין את מי אנחנו הולכים לתקוף, נעשה עליו חיפושים לגיטימיים ברחבי הרשת
  1.  נשאל את Google (הכי פשוט והכי מהיר).
  2.  נבדוק באתרים פיננסיים (גודל החברה, מיקומים, מנכ"לים, כספים).
  3. רשתות חברתיות (שמות של עובדים, חברים של העובדים, בלוגים).

איזה מערכות יש לו?
אנחנו יודעים שהקורבן משתמש בפלטפורמה של אינטרנט ודרך הפעולה להשלמת המשימה היא לפגוע באתר והלקוחות שלו על מנת שיעברו לחברה ששכרה אותנו למשימה, אנחנו יודעים שבכל העסק יושב איזה שרת אינטרנט שמפעיל את האתר.

על מנת שנוכל למקד את נקודת הפריצה שדרכה נפגע באתר נבדוק את דרכי התקשורת עם הקורבן, ננסה להבין את גודל התשתית ואת ערוצי התקשורת שלו, נחפש את החשיפות המתאימות להתקפה ולהעלמת העקבות.

יש עשרות כלים לזיהוי חשיפות שמאפשרות לתוקף למצוא לו את ההתקפה המתאימה.


Nmap
אחד הכלים הותיקים והמפורסמים בתחום מכיל בתוכו המון אפשריות, ובעצם הכלי סריקה האמין ביותר שקיים,ניתן לזהות את מערכות ההפעלה, הפורטים ואת ה Services שרצים על השרת, והוא ניתן להורדה מהאתר: http://nmap.org/ , יש לו גרסאות  Gui ו Console ומגיע עם Backtrack , הוא מפורסם גם בתעשיית הסרטים וניתן לראות בסרטים כמו :
Matrix Reloaded, Bourne Ultimatum, Die Hard 4.

דוגמה לסריקה
#: nmap -A 192.168.1.1


ניתן לראות Ports פתוחים, מערכות ההפעלה, שמות  ברשת וכו'.
סריקה כזאת חושפת את התוקף כי היא משאירה חותמת מאוד ברורה במערכות הניתור של הקורבן.



ניתן לראות את הזמנים המאוד קצרים בין חבילה לחבילה שנשלחת מהתוקף.
ניתן לבצע סריקות יותר איטיות שלוקחות יותר זמן אבל מוסתרות יותר, האות T מייצגת את הזמן של הסריקה, כש 1 היא האיטית ביותר עד 5 שהיא המהירה ביותר.

#: nmap -T1 -A 192.168.1.103



ניתן לראות את שהזמנים יותר ארוכים בין חבילה לחבילה.


Zombie
שימוש במחשב "Zombie" שיבצע בשבילנו את הסריקה מבלי לחשוף את עצמנו, איך בדיוק זה עובד?
בתוך המושג Zombie מסתתרת בעייה עמוקה והיא ברמת ההתנהגות הבסיסית של הפרוטוקול Tcp/Ip , כל חבילה שנשלחת מכילה מספר רץ, בכל חבילה יש מספר שעולה + 1 כאשר מגיעה חבילה חדשה, ובעצם ע"פ הקפיצות ניתן לחזות אם ה Port פתוח או לא.

#: nmap -sI Zombie-Address -PN -v Victim-Address


הפעולה שמאחורי הקלעים:

שליחת Packet SYN/ACK ל Zombie


  • החבליה שחוזרת לנו מהזומבי היא RST ובעצם מעלה את ה ID באחד.


שליחת חבלית  Spoof  Packet SYN.

  • נשלחת דרכנו חבילה מטעם הזומבי.


הקןרבן מחזיר Packet SYN/ACK


  • מעלה את ה ID בזומבי ב 1.

שליחת Packet SYN/ACK נוסף ל Zombie



החבילה שחוזרת לנו חוזרת + 1 , כלומר אם ננתח את השיטה בחבילה הראשונה שנשלחה המספר ID עלה ב 1 כאשר אנחנו שולחים את החבילת ה Spoof שלנו ה Victim שולח חבילת SYN/ACK בעקבות הבקשה של SYN ששלחנו בחבילה, הזומבי מסרב לחבילה ומחזיר חבילת RST ומעלה את ה ID שלו ב 1  פעם נוספת כששולחים חבילה נוספת של SYN/ACK לזומבי מקבלים חבילה RST שמעלה את ה ID באחד ובעצם אם ה ID קפץ 3 פעמים ,המסקנה שה Port אצל ה Victim פתוח במקרה וחבילה החוזרת מה Zombie וה ID קפץ רק פעמיים זה אומר שה Port כנראה סגור כי חבילת ה Spoof לא הגיעה ליעד שלה.

ניתן לראות איך זה קורה בפועל מאחורי הקלעים:
#: nmap -sI Zombie-Address -PN -r --packet-trace -v Victim-Address 


 Httprint
כלי לזיהוי האפליקציה שמריצה את האתר, הכלי מאוד פשוט והוא עובד על ניתוח של החבילות שחוזרות, מגיע עם Backtrack, להורדה: http://net-square.com/httprint/


במקרה שלנו אנחנו רוצים לדעת אם המערכת עובדת על IIS או Apache , ה Response שנקבל שונים מאפליקציה לאפליקציה ובנוסף נקבל את הגרסה הנוכחית על מנת שנוכל להתאים לה התקפה.


כיצד ניתן לבלבל את התוקפים?

FireWall
נחשוף לעולם כמה שפחות, הגדרות נכונות ב Firewall והסרה של שירותים שלא נחוצים למערכת שלנו.
Packet TTL
לשנות את זמני ה TTL שהמערכת מחזירה, כלומר ה Hops שיכולים לעבור ב Datagram שבחבילה, ובכל Hop  שאנחנו עוברים בדרך ה TTL קטן באחד, ברגע שאנו עוברים יותר Hops מהכמות המוגדרת ב TTL נקבל הודעת ICMP Time Exceeded, ב Windows הגדירו את ב TTL כ 128 וב Linux כ 64.

שינוי TTL ב Windows Server 2008
נפתח את ה RegEdit ונלך למפתח:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters


נוסיף Dword 32 bit נגדיר את ה TTL הרצוי, בין 1 - 255, חשוב לא להגדיר מספר נמוך מידי, נשמור אותו כ DefaultTTL



Http Response
שינוי ה Response שחוזרים לנו ב Http , לדוגמה אם נגיע לדף שלא קיים נקבל הודעת שגיאה יחודית עבור האפליקציה שמריצה את האתר.


הדף שחזר לנו מראה לנו הודעת שגיאה של IIS7 שמצביעה על מערכת הפעלה מסוג Windows, ניתן לשנות את הדפים ובכך לבלבל את הסריקות של התוקף.



קבצי השגיאות מסוג Html והם ממוקמים בספרייה:
C:\inetpub\custerr\en-US\
ניתן לשנות את הניתוב עבור דפי השגיאות ברמת ה IIS ב Error Pages.


לסיכום:
איסוף המידע הוא קריטי עבור שלב ההתקפה, ובעצם כל חשיפה שיש על הקורבן מקרבת את התוקף לפריצה שהוא רוצה להפעיל - Exploits, DOS attack , Brute Force וכדומה.


יום שבת, 15 בינואר 2011

Picasa Api With C#



לאחר המאמר שלי בנושא התממשקות ל Facebook החלטתי לעשות מאמר נוסף על התממשקות ל Picasa - תוכנת האחסון תמונות ב Google, אז גם פה הנושא הוא מורכב ואפילו יותר מורכב מ Facebook (אם חשבתם ש Facebook מסובך תראו מה Google עשו לנו).

קצת רקע:
הרעיון של ה Api  הוא לאפשר לאפליקציות צד שלישי לעבוד מול התכנים והחשבונות של המשתמשים ובעצם לקבל תשתית מלאה לביצוע שאילתות על התוכנות של Google.

גוגל מאוד רחבה מבחינת התשתיות שהיא נותנת עבור חברות צד שלישי כמעט כל המוצרים של גוגל מכילים רכיבי Api עבור התממשקות חיצונית ואם סתם בא לי לבנות עכשיו מערכת לניהול תמונות אני יכול לעשות זאת בעזרת ה Api של Picasa בנקודת הנחה שהיא מיועדת למשתמשים עם חשבון ב Picasa וכך אני יכול לעשות לשאר האפליקציות של Google כמו Google Maps , Google Earth , Gmail ועוד.

יופי שזה אפשרי אבל מה בנוגע לפרטיות של החשבונות שלי?

מרבית ה Apis בדומה ל Faceook / Google מכילים מספר כלי אימות והצפנה על מנת לשמור על מידע של המשתמשים, גוגל מאפשרת זאת במספר דרכים שעליהם אני אפרט בהמשך, כרגיל גם המאמר הזה מחולק לחלקים, יצירת חשבון ב Google והוספת Domain ב Webmaster tool, תהליך ה Authentication, ביצוע שאילתה וקבלת נתונים.

הגדרות ב Google
תחילה יש ליצור חשבון ב Google (אני לא מאמין שלמשהו אין אבל בכל מקרה זה חובה), לאחר מכן יש להצהיר על הדומיין שלנו בגוגל דרך הלינק https://www.google.com/accounts/ManageDomains , יש לרשום את הדומיין שלנו על מנת ש Google היפתח לנו את הגישה ל Api




ניתן לבחור דרכים שונות לאימות אני בחרתי Add a meta tag to your site's home page , זאת שורת Metadata שנשתול בעמוד הראשי של ה Domain שלנו.


 
לאחר שהוא יגש אליו ויאמת אותו הוא יכריז שהוא Active וייצר לנו מספר מפתחות בדומה ל Facebook


  • Target Url Path Prefix - הכתובת המלאה של הדף שהולך להתחבר ל Picasa ב domain שלנו לדוגמה: http//www.mysite.com/picasa.aspx
  •  Domain Description - ניתן לתת תיאור אבל הוא לא חובה.
  • Upload New X509 - ניתן לתת Certificate שעליו נדבר בהמשך אבל גם הוא לא חובה.


כלים נחוצים:

Google Data Protocol - המחלקות שאיתם נתממשק דרך הקוד שלנו באתר, התמיכה מרובה וניתן למצוא מחלקות להמון שפות כמו Java , Javascript , PHP,Python,.Net , להורדה: Client Libraries

OpenSSL - כלי ליצירת Certificates חינמי, להורדה: OpenSSL - Windows

סקירה על המחלקות שבהם נשתמש:
  • Google.GData.Client.dll
  • Google.GData.Extensions.dll
  •  Google.GData.Photos.dll

מחלקות ה Client  וה Extensions קבועות עבור כל סוגי ה Apis ש Google מאפשרת לנו להתממשק אליהם עבור כל Api יש קובץ התממשקות משלו, במקרה של אנחנו משתמשים ב Photos אם ההיתי מעוניין להשתמש בשירות אחר עליי לצרף את המחלקה שמייצגת אותו לפרוייקט.

Authentication

תהליך האימות של האפליקציה שלנו גמיש , עבור תוכנות מבוססות Web ותוכנות מבוססות Desktop גם רמת האבטחה ניתנת לשינוי בחלק זה נעבור כיצד ניתן לאמת את החשבונות של המשתמשים.

קיימים 2 ערוצי התממשקות:

1.Client Authentication

הכנסת שם משתמש וסיסמא לחשבון של Google , הדרך הזאת נפוצה באפליקציות Desktop שמעוניינות להתממשק ל Picasa אבל מאוד לא מומלצת לאתרים שמעונינים להתממשק ל Picasa כי המשתמש צריך להכניס את פרטי ההתחברות שלו בתוך האתר שלנו, סביר להניח שהוא לא יעשה את זה מטעמי אבטחת מידע.


2. Web Application Client Authentication

הדרך הטובה ביותר להתממשקות של אתרים צד שלישי למערכות ה Api ללא צורך להתממשקות דרך האתר אלא בעזרת Token של ה Session של המשתמש, כלומר המשתמש צריך להיות מחובר לחשבון שלו ב Google , והמערכת שלנו לוקחת את ה Session שלו מ Google.

אם אנחנו לא נשתמש ב Certificate נראה את ההודעה הבאה:
נראה סימן קריאה צהוב שאומר רק אם המשתמש סומך על האתר שיאשר את הכניסה כלומר Google לא מכיר את ה Domain שלנו כאתר אמין, אלא אם כן נצור Certificate ונעלה אותו ל Google ב Manage Domain שהראיתי מקודם אבל אל דאגה נעבור גם על זה.
עכשיו נעבור על הקוד שלנו על מנת להבין את התממשקות, תחילה ניצור לנו אתר אינטרנט חדש ב Visual Studio, ונצרף אליו את המחלקות מה Sdk של Google , נלך לפונקציה Page_Load.

הבדיקה הראשונה שלנו בודקת אם אין לנו Token שגוגל הפיק לנו עבור המשתמש, אם אין Token נעשה את הקוד הבא:


 if (Request["token"] == null)
{
  Session["tokan"] = null;
  string d = AuthSubUtil.getRequestUrl("http://mywebsite.com/picasa.aspx", 
  "http://picasaweb.google.com/data/", false, true);
   Response.Redirect(d);
}
עכשיו נעבור לנו על הקוד, יש לנו אובייקט שנקרא AuthSubUtil שהוא הכלי שמנהל לנו את התממשקות , GetRequest זאת הפונקציה ששולחת את המשתמש מהאתר שלנו לאתר של Google על מנת שיאשר את התתחברות ל Domain שלנו, הפונקציה מקבלת קבוצה של פרמטרים שעליהם אני אפרט:

1.Url - הכתובת הראשונה שאנו רואים http://mywebsite.com/picasa.aspx זאת הכתובת שהמשתמש יחזור אליה מ Google לאחר שיאשר את ההתממשקות.

2.Url Api - זאת הכתובת שמייצגת את הכתובת של ה Api של Google לשם המשתמש יעבור לאחר שהפונקציה הזאת תופעל - לכל מוצר יש את כתובת ה Api שלו.

3.Bool Secure - מייצג אם יש Certificate עבור ה Domain שלנו.

4.Bool Session - אם לקבל מפתח חד פעמי שניתן לבצע איתו פעולה בודדת או לקבל מפתח של ה Session עצמו שניתן לבצע בעזרתו פעולות רבות.

לאחר מכן נבצע Redirect עלמנת לתפוס את ה Token שחזר לנו.


 Google Certificate

יצירת Certificate מתבצעת בעזרת הכלי OpenSSL (להורדה גש לשלב "כלים נחוצים"), פורמט התעודה שלנו הוא X.509 , נצטרך לעשות Private Key ואת ה Certificate Key של התעודה, נעשה זאת בעזרת הפקודה הבאה:

C:\OpenSSL-Win32\bin>openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj
"/C=US/ST=CA/L=Mountain View/CN=www.mysite.com" -keyout
test_key.pem -out test_cert.pem 

השורה האדומה מסמנת לנו את פרטי החברה שעליה רשום ה Certificate שלנו:
C-Country
ST- State
L-Location
CN - Company name

לאחר פקודה זו נוצרו לנו 2 קבצי Pem שאת קובץ test_cert.pem נעלה ל Google, ב Manage Domains שראינו בהתחלה.

השלב הבא הוא יצירת קובץ Pfx שנוכל לעבוד בו עם האפליקציה שלנו ב .Net שמכיל את המפתח הפרטי שלנו, נריץ את הפקודה הבאה:

C:\OpenSSL-Win32\bin>openssl pkcs12 -export -in test_cert.pem -inkey test_key.pem
-out test_cert.pfx -name "MyCertificate"

עכשיו נחזור לקוד של ההתממשקות:

string d = AuthSubUtil.getRequestUrl("http://mywebsite.com/picasa.aspx", "http://picasaweb.google.com/data/", true, true);

ונסמן את ה bool Secure כ True, נעלה את קובץ ה Pfx לאתר שלנו.

נוסיף לנו פונקציה נוספת בקוד שלנו שבה נשתמש בהמשך:

private AsymmetricAlgorithm getRsaKey()
{
  X509Certificate2 cert = new X509Certificate2(Server.MapPath("~/test_cert.pfx"),"certificatepassword");
  RSACryptoServiceProvider privateKey = cert.PrivateKey as RSACryptoServiceProvider;
  return privateKey;
}

הפונקציה תקרא מקובץ ה Pfx את המפתח הפרטי שלנו ו Google תאמת אותו מול קובץ ה Pem שהעלנו עבור ה Domain ב Google.

עכשיו נחזור לנו להמשך התהליך, נניח שקיבלנו את ה Token שלנו מ Google עכשיו נעשה בדיקה אם יש לנו Token נריץ את הקוד הבא:

 if (Request["token"] != null)

{
  string token = Request.QueryString["token"];
  Session["token"] = AuthSubUtil.exchangeForSessionToken(token, null).ToString();
  Response.Redirect(Request.Url.AbsolutePath, true);
}

 מה שאנחנו בעצם עושים הוא לקחת את ה Token מה Request ונבקש מ Google בעזרת הכלי AuthSubUtil שיחזיר לנו Token של ה Session , הפונקציה exchangeForSessionToken מקבלת 2 ערכים הראשון הוא ה Tokan ש Google החזיר לנו בשלב ההתממשקות הראשונית, הפרמטר השני זה ההצפנה , אם אין לנו Cetificate Private Key נשלח Null , אם יש Cetificate Private Key נקרא לפונקציה שקוראת את המפתח מקובץ ה Pfx שיצרנו.

Session["token"] = AuthSubUtil.exchangeForSessionToken(token, getRsaKey()).ToString();


ב 2 המצבים צריכים לטעון את ה Token שחוזר ב Session של האתר שלנו על מנת שנוכל לבצע יותר מפעולה בודדת, ובעצם סיימנו את תהליך ההתממשקות ועכשיו נעבור לשאילתות מול ה Api.

ביצוע שאילתות מול ה Api

לאחר שסיימנו את תהליך ההתממשקות ניתן להתחיל לבצע שאילתות מול ה Api של Google, תחילה נצהיר על האובייקט:
GAuthSubRequestFactory - שהוא מכיל בתוכו את ה Tokan שבתוך ה Session של האתר שלנו , ובעצם נשלח ל Google ברגע שנבצע שאילתה, בנוסף צריך להגדיר את ה Api של התוכנה Picasa שהקוד שלה הוא "lh2" ,שוב פעם לכל Api יש את הקוד שלו (לרישמת הקודים עבור שאר האפליקציות), וכמובן נשלח לו את ה Domain שלנו כ ApplicationName.

GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("lh2", "http://www.mywebsite.com/");
authFactory.Token = Session["token"].ToString();
 
השלב הבא הוא להצהיר על ה Service עצמו, האובייקט שלנו הוא PicasaService שמקבל ApplicationName שהגדרנו באובייקט GAuthSubRequestFactory.
 
PicasaService myservice = new PicasaService(authFactory.ApplicationName);

נצהיר על סוג השאילתה שלנו (Query) , יש המון סוגים של שאילתות, בדוגמה שנראה פה נשתמש ב PhotoQuery שהיא שאילתה עבור התמונות ללא קשר לאלבום אבל ניתן לבצע שאילתה גם על אלבומים בעזרת האובייקט AlbumQuery.

 PhotoQuery query = new PhotoQuery(PicasaQuery.CreatePicasaUri("default"));

ה default מייצג את ה User במקרה של Client Authentication נשלח שם משתמש וסיסמא:
PhotoQuery query = new PhotoQuery(PicasaQuery.CreatePicasaUri(username,password));


אובייקט PicasaQuery בונה לנו את ה Url שאליו אנו פונים ב Api.

את התוצאות שחוזרות לנו בפורמט Xml נאחסן באבייקט PicasaFeed.
PicasaFeed feed = myservice(query)

מה שנשאר לנו לעשות הוא להריץ ריצה על ה Feed על מנת לחלץ משם את התמונות שחזרו לנו מה Api.
foreach (AtomEntry aentry in feed.Entries)
{
myphotos = myphotos +  aentry.Content.Src.ToString();
}
 
קוד מלא לדוגמה:
 
using Google.GData.Photos;
using Google.GData.Client;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using System.Net;

public partial class picasa : System.Web.UI.Page
{
   public string myphotos = "";
   public string myerror = "";
   protected void Page_Load(object sender, EventArgs e)
   {
      if (Session["token"] != null)
     {
       get_images();
     }
     else if (Request["token"] != null)
     {
       string token = Request.QueryString["token"];
       Session["token"] = AuthSubUtil.exchangeForSessionToken(token, null).ToString();
       Response.Redirect(Request.Url.AbsolutePath, true);
     }
     else if (Request["token"] == null)
      {
       Session["tokan"] = null;
       string d = AuthSubUtil.getRequestUrl("http://www.mywebsite.com/picasa.aspx", 
       "https://picasaweb.google.com/data/", false, true);
       Response.Redirect(d);
      }
}

private void get_images()
{
  GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("lh2", "http://www.mywebsite.com/");
  authFactory.Token = Session["token"].ToString();
  PicasaService myservice = new PicasaService(authFactory.ApplicationName);
   picasaser.RequestFactory = authFactory ;
   try
   {
     PhotoQuery query = new PhotoQuery(PicasaQuery.CreatePicasaUri("default"));
     PicasaFeed feed = myservice.Query(query);
     foreach (AtomEntry aentry in feed.Entries)
    {
      myphotos = myphotos + aentry.Content.Src.ToString() ;
    }
   }
   catch (GDataRequestException gdre)
   {
     HttpWebResponse response = (HttpWebResponse)gdre.Response;
     //bad auth token, clear session and refresh the page
      if (response.StatusCode == HttpStatusCode.Unauthorized)
     {
      Session["tokan"] = null;
      Response.Redirect(Request.Url.AbsolutePath, true);
     }
     else
     {
       Response.Write("Error processing request: " + gdre.ToString());
     }
   }
}

private AsymmetricAlgorithm getRsaKey()
{
  X509Certificate2 cert = new X509Certificate2(Server.MapPath("~/test_cert.pfx"),"mycertificatepassword");
  RSACryptoServiceProvider privateKey = cert.PrivateKey as RSACryptoServiceProvider;
  return privateKey;
 }
}

לאתרי מידע נוספים:

בהצלחה...

יום שלישי, 11 בינואר 2011

#Facebook api with C



התממשקות ל Facebook זה לא דבר פשוט עם #C ולמעשה דורשת מספר הכנות ושינויים בשביל להשלים את התהליך, המאמר מחולק ל 3 חלקים, החלק הראשון נוגע בהגדרות החשבון שלנו ב Facebook החלק השני נוגע בחלקים הדרושים על מנת לבצע את הגדרות ההתממשקות שלנו כמו שצריך, והחלק האחרון נוגע באפליקציה שלנו.

הגדרות ב Facebook
הכרה של Facebook במערכת שלנו, על מנת לעשות זאת יש ליצור אפליקציה בתוך Facebook עצמו, תחילה יש ליצור חשבון ב Facebook, השלב הבא הוא להיכנס לקישור Developers  (מרכז האפליקציות בחשבון שלנו ב Facebook),לבחור ב See My Apps או ליצור אפליקציה חדשה בלחיצה על Create  one.

בשלב זה תכניסו תיאור ושם לאפליקציה ותשמרו, Facebook מייצר מספר מפתחות עבור האפליקציה שלנו.

appId
מספר חד ערכי עבור האפליקציה שלנו.

apiKey
מפתח עבור ה Api.

appSecret
מפתח עבור האפליקציה.

שים לב! שמור את המפתחות האלה במקום בטוח!



חשוב מאוד להגדיר את כתובת האתר שהולך לעבוד מול האפליקציה הזאת על מנת לאשר את החיבור שלו ל Api של Facebook , חשוב לציין נקודה שעדיין מוקדמת בתהליך אבל קריטית - עם ננסה להתממשק דרך אתר מקומי - (LocalHost) שאותו נפתח בשלבים הבאים, לא נוכל לעשות זאת , האתר חייב להיות עם כתובת חוקית.

התקנת רכיבים לצורך התממשקות:
על מנת לאפשר התממשקות אנחנו צריכים להוריד את ספריות ה Api של Facebook לאתר שלנו ולעשות שינויים ב web.config וב Framework שלנו.

Framework
יש להוריד ולהתקין את Framework 3.5.

Facebook Api
מחלקות ה Api של Facebook להורדה FacebookSDK.

ה Api מורכב ממספר מחלקות שמחוייבות להיות קשורות לאפליקציה שלנו על מנת לעבוד:

Facebook.dll
מחלקות כלליות של ה Api.

 Facebook.Web.dll
מחלקות ה Web של ה Api.

Microsoft.Contracts.dll
מערכת חדשה של מיקרוסופט לטיפול בשגיאות ובקלט \ פלט.
להורדה Microsoft contracts

 Newtonsoft.Json.dll
מחלקה לעבודה עם Json ו .Net.
להורדה Json.net

הקמת פרויקט התממשקות
הדבר הראשון שנעשה הוא פרויקט חדש ב Visual Studio של Asp.net ב Framework 3.5, אח"כ נעשה Reference למחלקות שהורדנו



יש לערוך את קובץ ה web.config על מנת שיוכל להכיר את כל ה components.
לפני התגית  </configsections> יש להכניס:
<section name="facebookSettings" type="Facebook.FacebookConfigurationSection" />

אחרי התגית <\connectionstrings>יש להכניס:
<facebooksettings appid="xxxxxxxxxxxx" appsecret="xxxxxxxxxxxx"
cookiesupport="true" / >
בנקודה זו יש להכניס את המפתחות ש Facebook יצר לנו עבור ההתממשקות ל Api.

נערוך את דף ה Index של האתר שלנו:
נוסיף לתגית < html> בראש העמוד:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">


נכניס לתוך ה < body>  את הטופס הבא:

<form id="form1" runat="server">
    <div>
              <div id="fb-root">
     </div>
     <fb:login-button autologoutlink="true" onlogin="window.location.reload();"
        perms="email"></login-button>
     <script type="text/javascript">
        window.fbAsyncInit = function () {
         FB.init({ appId: 'xxxxxxxxxxxx', status: true, cookie: true, xfbml: true, 
         reloadIfSessionStateChanged:  true });
         };
         (function () {
         var e = document.createElement('script');
         e.type = 'text/javascript'
         e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
         e.async = true;
         document.getElementById('fb-root').appendChild(e);
         } ());
</script>
User ID:<label id="LabelUserid" runat="server"></label>
First Name:<label id="LabelFirstName" runat="server">lt;/label>
Last Name:<label id="LabelLastName" runat="server">lt;/label>
<img id="imageUser" runat="server" visible="true" /></img</div>
</form>

עכשיו נערוך את הקוד שמאחרי הדף:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Facebook;
using Facebook.Web;
using System.IO;

public partial class facebook : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
   {
       FacebookApp fapp = new FacebookApp();
       Authorizer auth = new Authorizer(fapp);
       auth.Perms = "email";

       if (auth.IsAuthorized())
      {
        LabelUserid.Text = fapp.UserId + "";
        JsonObject result = (JsonObject)fapp.Api("/me");
        LabelFirstName.Text = (String)result["first_name"];
        LabelLastName.Text = (String)result["last_name"];
        imageUser.ImageUrl = "http://graph.facebook.com/" + fapp.UserId + "/picture
        ?type=large";
        imageUser.Visible = true;
      }
   }
}

קיבלנו אובייקט Json מה Api ועכשיו אנו שולפים את הפרמטרים של ה Profile של המשתמש באפליקציה בעצם ביצענו Login in ל Facebook, ה Api עם המון אפשרויות וניתן לעשות דברים נוספים כמו הוספת תגובות, קריאה והעלת תמונות ועוד ,החלק העיקרי הוא שלב ההתממשקות ובעצם כל אפליקציה שניצור ב Facebook מחייבת התחברות של המשתמש לחשבון האישי שלו כמובן שזה מצריך אישור של המשתמש.

הדף של האפליקציה שלנו:
הדף לאחר ההתממשקות:

נשמור את הפרויקט ונעלה אותו לשרת.
בהצלחה...

יום שבת, 8 בינואר 2011

Managed .Net RootKit

RootKit או בעברית "ערכת שורש" מאפשרת לתוקף לשנות תהליכים במערכת ההפעלה של הקורבן, ע"י שינוי תוכניות הרצות במערכת ההפעלה , ולהזריק קוד לתהליכים רצים  ולשנות את אופן עבודתם, לדוגמה: התוקף מתקין איזה תולעת או סוס טוריאני ע"ג הקורבן אבל מעוניין להסתיר אותו מעיניי המשתמש או מתוכנת האנטי וירוס, עליו יהיה להפעיל בנוסף RootKit על מנת להסתיר אותו מהבקשות של המשתמש או מתוכנות אחרות מול מערכת ההפעלה, אין דבר יותר גרוע מלהיות מודבק ב RootKit כי קיים קושי רב בלמצוא ולנטרל אותו.

תהליך כתיבת RootKit הוא מסובך ומצריך ידע רב במערכות הפעלה ובשפות נמוכות כמו Assembler ו C, אבל ניתן למצוא מידע רב באינטרנט ובספרים רבים כמו The RootKit Arsenal, קיימים מספר שכבות ל RootKit שקובעות את עוצמתו:

  • Virtualised - השכבה החזקה ביותר שבעצם מוטמעת בשלב העלייה של המחשב, מתחברת לחומרה ואח"כ מערכת ההפעלה עובדת מול ה RootKit והוא מעביר לחומרה.
  • Kernel Mode - הפעלת RootKit מה Kernel של מערכת ההפעלה.
  • Library level / User Mode - שינוי הספריות שעובדות מול ה Kernel.
  • Application Mode - שינוי ספריות של האפליקציה.
ה RootKit שנכתוב הוא ברמת ה Application Mode ובעצם נשנה את אופי העבודה של התוכנית שלנו.

תחילה יש להכיר את המנגון של .Net , דבר ראשון כל כתיבה של תוכנה ב .Net מצריכה עבודה מול Framework של מיקרוסופט ובעצם בלעדיו לא ניתן להריץ את הקוד שכתבנו כי הוא מצריך את המחלקות ב Framework, בזמן הריצה הקוד שלנו מתורגם לשפת בניים שנקראת IL - Intermediate Language שזאת השפה שנשלחת למנגנון CLR - Common Language Runtime שהיא שכבה וירטואלית שמפרידה בין מערכת ההפעלה לתוכנה שלנו ומשם עוברת למנגון JIT - Just In Time שממיר אותה לשפת מכונה תוך כדי ריצה.

*בעקבות התהליך הזה זמני התגובה של .Net איטיים יותר מאשר שפות נמוכות יותר כמו C ו C++.

חסרון נוסף ב .Net שניתן לחשוף את הקוד של התוכנה ע"י תוכנות Decompiler רבות, המפורסמת שבהן היא ה Reflector של חברת RedGate שחושפת  את הקוד בצורת טקסט וניתן לראות את הפונקציות והמשתנים בצורה נוחה מאוד בניגוד ל Disassembler של C \ C++ כמו IDA ששם הכל כתוב ב Assembler.


הנקודה החשובה היא שלא רק הקוד שלנו חשוף אלא גם הקוד של ה Framework חשוף, המחלקות שהתוכנית משתמשת ניתנות לצפייה, רק כדי לחדד את הנקודה אם אני אנסה להיכנס למחלקה System.IO דרך ה Visual Studio אני אוכל לראות רק את ההצהרות על הפונקציות ולא מעבר לזה.


לעומת זאת אם אני אבדוק את מחלקת System.IO ב Reflector אני אראה מה קורה בתוך הפונקציות ובכלל את כל המחלקות והמשתנים:




עכשיו נעבור על התוכנית שלנו, התוכנית בודקת כמה כוננים קשיחים יש על המחשב, המחלקה שנשתמש בה היא DriveInfo שנמצאת במרחב שמות של System.IO:

using System.IO;

 static void Main(string[] args)
{
     DriveInfo [] Mydrives = DriveInfo.GetDrivers();
     for(int i = 0; i < mydrivers.length; i++)
     {
          try
          {
                Console.WriteLine(mydrives[i].Name);
           }
           catch(Exception)
           {

           }
      }
}
ה RootKit שלנו הולך להעלים לאפליקציה את כונן :C ולהראות את שאר הכוננים, על מנת לעשות זאת יש להבין איפה מרחב השמות System.IO נמצא, ניתן לזהות את מרחב השמות ע"י תוכנות רבות כמו Process Hacker או באמצעות ה Reflector ע"י לחיצה על הפונקיצה GetDrivers.

המחלקה נמצאת בקובץ mscorlib.dll שהוא חלק מה Framework עליו התוכנית מבוססת, קובץ זה מכיל את מחלקות הליבה של ה Framework , והוא הקובץ המרכזי של ה Framework שלנו, הוא ממוקם ב GAC - Global Assembly Cache , זאת תקייה שמכילה את ב Cache של כל ה SharedLibarys של ה .Net, ניתן להגיע לספריה זאת מ
C:\Windows\assembly
היא לא ניתנת לשינוי דרך ממשק ה Windows עצמו, ניגש אליה דרך ה Console
C:\WINDOWS\assembly\GAC_32\




כלים שיעזרו לנו להשלים את המשימה:

ILDASM- תוכנה של מיקורוספט שעושה Disassmbler לקבצי .Net היא נמצאת בספריה Microsoft.SDK שמותקנת כחלק מ Visual Studio
C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bin\

ILSAM - גם זאת תוכנה של מיקרוספט שעושה לנו קבצי DLL חדשים מקבצים בשפה IL , היא מגיעה לנו עם ה Framework
C:\Windows\Microsoft.NET\Framework\v2.0.50727\

*נקודה למחשבה למה מיקרוספט שיחררו את הכלים האלה אם הם יכולים לפגוע במחלקות של ה Framework עצמו?

לאחר שמצאנו את הפונקציה GetDrivers בתוך ה System.IO ניתן להמיר דרך ה Reflector את הפונקציה לשפות רבות ואחת מהן היא IL. 

נוכל לראות את החתימה של הפונקציה:
.method public hidebysig static class System.IO.DriveInfo[] GetDrives() cil managed

נמיר את קובץ ה mscorlib.dll לקובץ IL בפקודה הבאה:
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin>ildasm /out=C:\mscorlib.il /nobar /linenum /source C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll
 
עכשיו נוצר לנו קובץ ב :C עם הקוד של mscorlib.
נחפש את חתימת הפונקציה בקובץ
 

אם נסתכל טוב בקוד נוכל לראות שהפונקציה קוראת לפונקציה פנימית הנקראת GetLogicalDrive אפשר כמובן לתקוף אותה במקום את הפונקציה הזאת.
 
נראה איך הפונקציה GetDrivers במרחב שמות System.IO נראת ב #C:
 
public static DriveInfo[] GetDrives()
{
   string[] logicalDrives = Directory.GetLogicalDrives();
    DriveInfo[] infoArray = new DriveInfo[logicalDrives.Length];
    for (int i = 0; i < logicalDrives.Length; i++)
    {
       infoArray[i] = new DriveInfo(logicalDrives[i]);
     }
    return infoArray;
}

מה שאפשר לעשות הוא בעצם להתחיל את הלולאה מ - 1 על מנת לדלג על הכונן שב 0, על מנת לעשות זאת נפתח את קובץ ה IL שיצרנו ונשנה את השורה 449664 מ 0 ל 1.

כמובן ניתן לעשות שינויים רבים אבל לצורך הדוגמה זה מספיק.


עכשיו ניצור את ה DLL מחדש, נרשום את הפקודה הזאת:
C:\Windows\Microsoft.NET\Framework\v2.0.50727>ilasm /debug /dll /quiet /output=c:\mscorlib.dll c:\mscorlib.il
יש לעתיק את ה DLL שיצרנו לספריה של ה Framework:
C:\> copy mscorlib.dll c:\windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\
 
עלמנת להכניס את ה DLL שיצרנו לתוקף יש לבצע 2 פקודות:
 
Ngen - Native Image Generator
יש להסיר את ה DLL מהמנגנון
C:\Windows\Microsoft.NET\Framework\v2.0.50727>ngen unistall mscorlib
מחיקה מה Cache:
C:> rd /s /q c:\windows\assembly\NativeImages_v2.0.50727_32\mscorlib
חשוב מאוד לעשות את כל התהליך על תחנה וירטואלית על מנת לא לפגוע במערכת שלנו.
 
עכשיו נראה את התוצאה:
 
המחשב שלא מודבק:
 
 
 
המחשב המודבק:
 

 
ארז מטולה אשף אבטחת מידע רשם על כל הנושא הזה ספר מפורט שמסביר את הבעיה וכיצד ניתן להגן נגד איומים מהסוג הזה.
קישור לספר:
 
בהצלחה...