Re: brute-forcing a git commit hash

2019-02-19 חוט Sagi Ben-Akiva
ניסית להשתמש ב hooks ?
לדוגמא server side hook שנקרא update ?

פה יש דוגמא ל client side hook שמשנה את ה commit msg :
https://git-scm.com/book/en/v2/Customizing-Git-An-Example-Git-Enforced-Policy

On Tue, Feb 19, 2019 at 7:18 PM Tomer Brisker  wrote:

> הי צפריר,
>
> אכן שאלה מעניינת.
> קח בחשבון שהhash כולל בתהליך החישוב שלו גם את ה-timestamp של הקומיט, כך
> שגם אם תמצא commit message שעונה על התנאי, לא תוכל לשחזר את התוצאה בריצה
> מאוחרת יותר.
> מכיוון שאתה לא משנה את ה tree אלא רק את הודעת הקומיט עצמו, יתכן שתוכל לחשב
> את ה hash מבלי ליצור קומיט של ממש באמצעות git hash-object או פקודה דומה.
> לפרטים נוספים על איך המימוש הפנימי של כל האובייקטים עובד, ממליץ על הפרק
> הבא: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects
>
> On Tue, 19 Feb 2019 at 13:56, Tzafrir Cohen  wrote:
>
>> שלום,
>>
>>
>> השאלה שלי סוטה מהכיוון הכללי של הרשימה הזו בזמן האחרון ולמרבה הפליאה לא
>> קשורה לאף ידיעה ב־ynet.
>>
>>
>> אני מנסה לעשות משהו קצת דבילי: יש לי מאגר גיט קטן ואני מנסה לדאוג שה־hash
>> של ה־commit האחרון יהיה מה שבחרתי. ליתר דיוק: הגרסה המקוצרת שלו: מכיוון
>> שזהו מאגר קטן, מדובר על המינימום: שבעה תווי hex. כלומר: ‎ 16^7או ‎2^28. זה
>> כבר בתחום המעשי.
>>
>>
>> התחלתי מהסקריפט הבא:
>>
>> #!/bin/bash
>>
>> target="f00ba11"
>>
>> max=$((16 ** 7))
>>
>> commit_str() {
>> git show -s --'pretty=tformat:%h' HEAD
>> }
>>
>> commit_template="commit message title
>>
>> Try 
>>
>> "
>>
>> for i in `seq $max`; do
>>
>> if [ `commit_str` = "$target" ]; then
>>
>> break
>>
>> fi
>>
>> commit_msg=${commit_template//$i}
>>
>> git commit --amend -m "$commit_msg"
>>
>> echo -n "."
>>
>> done
>>
>>
>> הבעיה הראשונה הייתה לולאת ה־for ו־seq. הפלט שלו ענקי וזה מפוצץ את תהליך
>> באש עצמו (המכונה שלי הייתה קצת חנוקה עם זכרון). הפכתי את זה ללולאת for
>> רגילה יותר (לא היה לי כוח לבדוק אם לבאש יש משהו משלו):
>>
>> i=0
>> while [ $i -lt $max ]; do
>>
>> if [ `commit_str` = "$target" ]; then
>>
>> break
>>
>> fi
>>
>> commit_msg=${commit_template//$i}
>>
>> git commit --amend -m "$commit_msg"
>>
>> echo -n "."
>> : $((i++))
>>
>> done
>>
>>
>>
>> בשלב הזה ראיתי מהו הקצב, והחלטתי שהוא לא מספיק טוב ושאני יכול להריץ כמה
>> במקביל. העתקתי את התיקיה לעוד שלושה עותקים. לכל אחד שמתי קובץ בשם base_num,
>> בהתחלה קראתי את תוכנו למשתנה, ועכשיו שורת יצירת התבנית הפכה להיות:
>>
>> commit_msg=${commit_template//$base_num:$i}
>>
>> ואז שמתי לב שהאורך של ה־hash שמוצג לי כבר גדול מ־7. זה מוזר: נכון שאני
>> מייצר כל הזמן commit־ים לא מחוברים בכל הרצה של הלולאה, אבל מדי פעם רץ git
>> gc והוא אמור להיפטר מהם. ואז הבנתי שלא:
>>
>> 1. ה־reflog ממשיך להתייחס אליהם.
>>
>> 2. git gc מעיף אוטומטית רק commits בני שבועיים ויותר.
>>
>>
>> צריך להשתמש ב־git reflog expire: להגיד לו גם להתייחס לכל תוכן ה־log וגם
>> להפטר מכל מה שהוא מוצא, ולא רק מהישנים. את השינוי הבא לא להעתיק למקום אחר
>> אם אתם לא מבינים מה הוא עושה.
>>
>> באותה הזדמנות הוספתי גם קובץ בשם start שמוסיף את הערך שממנו צריך להתחיל
>> בפעם הבאה שמריצים (אם אני מפסיק באמצע).
>>
>> i=`cat start`
>> while [ $i -lt $max ]; do
>>
>> if [ `commit_str` = "$target" ]; then
>>
>> break
>>
>> fi
>>
>> commit_msg=${commit_template//$i}
>>
>> git commit --amend -m "$commit_msg"
>> case "$i" in *)
>> git reflog expire --all --expire=all
>> git gc --prune=all
>> echo $i >start
>> ;;
>>
>> esac
>>
>> echo -n "."
>> : $((i++))
>>
>> done
>>
>>
>> לא מצאתי איך אפשר לעשות commit ללא עדכון ה־reflog. האם זה אפשרי?
>>
>>
>> וכן, אני מניח שזו לא הדרך היעילה ביותר לעשות את זה. הצעות לדרכים יעילות
>> יותר יתקבלו בברכה.
>>
>>
>> -- צפריר
>> ___
>> Discussions mailing list
>> Discussions@hamakor.org.il
>> http://hamakor.org.il/cgi-bin/mailman/listinfo/discussions
>
>
>
> --
> יום טוב,
> תומר בריסקר
>
> ___
> Discussions mailing list
> Discussions@hamakor.org.il
> http://hamakor.org.il/cgi-bin/mailman/listinfo/discussions
___
Discussions mailing list
Discussions@hamakor.org.il
http://hamakor.org.il/cgi-bin/mailman/listinfo/discussions

Re: brute-forcing a git commit hash

2019-02-19 חוט Tomer Brisker
הי צפריר,

אכן שאלה מעניינת.
קח בחשבון שהhash כולל בתהליך החישוב שלו גם את ה-timestamp של הקומיט, כך שגם
אם תמצא commit message שעונה על התנאי, לא תוכל לשחזר את התוצאה בריצה מאוחרת
יותר.
מכיוון שאתה לא משנה את ה tree אלא רק את הודעת הקומיט עצמו, יתכן שתוכל לחשב
את ה hash מבלי ליצור קומיט של ממש באמצעות git hash-object או פקודה דומה.
לפרטים נוספים על איך המימוש הפנימי של כל האובייקטים עובד, ממליץ על הפרק
הבא: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

On Tue, 19 Feb 2019 at 13:56, Tzafrir Cohen  wrote:

> שלום,
>
>
> השאלה שלי סוטה מהכיוון הכללי של הרשימה הזו בזמן האחרון ולמרבה הפליאה לא
> קשורה לאף ידיעה ב־ynet.
>
>
> אני מנסה לעשות משהו קצת דבילי: יש לי מאגר גיט קטן ואני מנסה לדאוג שה־hash
> של ה־commit האחרון יהיה מה שבחרתי. ליתר דיוק: הגרסה המקוצרת שלו: מכיוון
> שזהו מאגר קטן, מדובר על המינימום: שבעה תווי hex. כלומר: ‎ 16^7או ‎2^28. זה
> כבר בתחום המעשי.
>
>
> התחלתי מהסקריפט הבא:
>
> #!/bin/bash
>
> target="f00ba11"
>
> max=$((16 ** 7))
>
> commit_str() {
> git show -s --'pretty=tformat:%h' HEAD
> }
>
> commit_template="commit message title
>
> Try 
>
> "
>
> for i in `seq $max`; do
>
> if [ `commit_str` = "$target" ]; then
>
> break
>
> fi
>
> commit_msg=${commit_template//$i}
>
> git commit --amend -m "$commit_msg"
>
> echo -n "."
>
> done
>
>
> הבעיה הראשונה הייתה לולאת ה־for ו־seq. הפלט שלו ענקי וזה מפוצץ את תהליך
> באש עצמו (המכונה שלי הייתה קצת חנוקה עם זכרון). הפכתי את זה ללולאת for
> רגילה יותר (לא היה לי כוח לבדוק אם לבאש יש משהו משלו):
>
> i=0
> while [ $i -lt $max ]; do
>
> if [ `commit_str` = "$target" ]; then
>
> break
>
> fi
>
> commit_msg=${commit_template//$i}
>
> git commit --amend -m "$commit_msg"
>
> echo -n "."
> : $((i++))
>
> done
>
>
>
> בשלב הזה ראיתי מהו הקצב, והחלטתי שהוא לא מספיק טוב ושאני יכול להריץ כמה
> במקביל. העתקתי את התיקיה לעוד שלושה עותקים. לכל אחד שמתי קובץ בשם base_num,
> בהתחלה קראתי את תוכנו למשתנה, ועכשיו שורת יצירת התבנית הפכה להיות:
>
> commit_msg=${commit_template//$base_num:$i}
>
> ואז שמתי לב שהאורך של ה־hash שמוצג לי כבר גדול מ־7. זה מוזר: נכון שאני
> מייצר כל הזמן commit־ים לא מחוברים בכל הרצה של הלולאה, אבל מדי פעם רץ git
> gc והוא אמור להיפטר מהם. ואז הבנתי שלא:
>
> 1. ה־reflog ממשיך להתייחס אליהם.
>
> 2. git gc מעיף אוטומטית רק commits בני שבועיים ויותר.
>
>
> צריך להשתמש ב־git reflog expire: להגיד לו גם להתייחס לכל תוכן ה־log וגם
> להפטר מכל מה שהוא מוצא, ולא רק מהישנים. את השינוי הבא לא להעתיק למקום אחר
> אם אתם לא מבינים מה הוא עושה.
>
> באותה הזדמנות הוספתי גם קובץ בשם start שמוסיף את הערך שממנו צריך להתחיל
> בפעם הבאה שמריצים (אם אני מפסיק באמצע).
>
> i=`cat start`
> while [ $i -lt $max ]; do
>
> if [ `commit_str` = "$target" ]; then
>
> break
>
> fi
>
> commit_msg=${commit_template//$i}
>
> git commit --amend -m "$commit_msg"
> case "$i" in *)
> git reflog expire --all --expire=all
> git gc --prune=all
> echo $i >start
> ;;
>
> esac
>
> echo -n "."
> : $((i++))
>
> done
>
>
> לא מצאתי איך אפשר לעשות commit ללא עדכון ה־reflog. האם זה אפשרי?
>
>
> וכן, אני מניח שזו לא הדרך היעילה ביותר לעשות את זה. הצעות לדרכים יעילות
> יותר יתקבלו בברכה.
>
>
> -- צפריר
> ___
> Discussions mailing list
> Discussions@hamakor.org.il
> http://hamakor.org.il/cgi-bin/mailman/listinfo/discussions



-- 
יום טוב,
תומר בריסקר
___
Discussions mailing list
Discussions@hamakor.org.il
http://hamakor.org.il/cgi-bin/mailman/listinfo/discussions