แปลงเอาต์พุต xxd เป็น shellcode


15

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

กฎระเบียบ

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

คุณโปรแกรมต้องใช้เวลาสามอาร์กิวเมนต์แรกเป็นสตริงที่มีการส่งออกของ xxd วิ่งที่มีการขัดแย้งไม่มีอื่น ๆ xxd some_fileกว่าชื่อไฟล์เช่นนี้ นี่คือตัวอย่างของสิ่งที่อาร์กิวเมนต์แรกจะมีลักษณะ:

00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY

คุณจำเป็นต้องใช้ส่วนตรงกลางที่มีไบต์ (8 คอลัมน์แรกหลัง:) และเปลี่ยนเป็น shellcode โดยการลบช่องว่างใด ๆ จากนั้นใส่\xก่อนแต่ละไบต์

นี่คือสิ่งที่ควรเป็นผลลัพธ์สำหรับอินพุตด้านบน (ละเว้นอาร์กิวเมนต์อื่น ๆ ):

\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e\x58\x58\x58\x58\x59\x59\x59\x59

คุณสามารถสันนิษฐานได้ว่าอาร์กิวเมนต์แรกจะเป็นผลลัพธ์ xxd ที่ถูกต้องเสมอโดยไม่มีข้อโต้แย้งอื่นใดนอกจากชื่อไฟล์

เอาต์พุตของคุณควรเป็นสตริงที่แบ็กสแลชเป็นแบ็คสแลชที่แท้จริงไม่ใช้เป็นอักขระเลี่ยง ดังนั้นเมื่อฉันพูดว่า "\ x65" ฉันไม่ได้พูดถึงไบต์ 0x65 หรือแม้แต่ตัวอักษร "A" ในรหัสมันจะเป็นสตริง "\ x65"

อาร์กิวเมนต์ที่สองระบุตำแหน่งที่ในเอาต์พุต xxd ที่ shellcode ควรเริ่มทำงานและอาร์กิวเมนต์ที่สามระบุตำแหน่งที่ควรจะจบ หากอาร์กิวเมนต์ที่สามคือ-1มันจะสิ้นสุดในตอนท้ายของเอาต์พุต xxd อาร์กิวเมนต์ที่สองและสามจะไม่เป็นลบเสมอยกเว้นเมื่อมีการโต้แย้ง-1

นี่คือกรณีทดสอบบางส่วน:

อาร์กิวเมนต์ 1:

00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY

อาร์กิวเมนต์ 2 7:, อาร์กิวเมนต์ 3: e(ทั้งคู่เป็นสตริงที่แสดงถึงเลขฐานสิบหก)

เอาท์พุท: \xc9\xcd\x80\xeb\x16\x5b\x31\xc0

อาร์กิวเมนต์ 1:

00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY

อาร์กิวเมนต์ 2 0:, อาร์กิวเมนต์ 3:2e

เอาท์พุท: \x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e

อาร์กิวเมนต์ 1:

00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY

อาร์กิวเมนต์ 2 a:, อาร์กิวเมนต์ 3:-1

เอาท์พุท: \xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e\x58\x58\x58\x58\x59\x59\x59\x59

รหัสที่มีจำนวนไบต์น้อยที่สุดจะเป็นผู้ชนะ ผู้ชนะจะได้รับการประกาศในเจ็ดวันในวันที่ 15 สิงหาคม 2016 (แต่การส่งหลังจากนั้นยังคงชื่นชม)

ปรับปรุง

ยินดีด้วยกับ@Adnanเพื่อชนะการท้าทาย!


เพียงเพื่อชี้แจงรายการสามารถส่งคืนสตริงหรือพวกเขาจะต้องพิมพ์หรือไม่
Jordan

การส่งคืนสตริงนั้นใช้ได้ตราบใดที่มันเป็นฟังก์ชั่นแลมบ์ดาหรืออะไรทำนองนั้น (ฉันได้อัปเดตกฎเพื่อระบุหลังจากคุณถาม)
addison

1
เราสามารถส่งคืนรหัส ASCII ปกติเมื่อรหัสสามารถพิมพ์ได้หรือไม่? เช่นแทน~ \x7eและเราสามารถกลับมา\tแทนได้\x09หรือไม่
orlp

@ orlp ขออภัยไม่จำเป็นต้องอยู่ในรูปแบบที่สอดคล้องกัน
addison

อาร์กิวเมนต์จำเป็นต้องเป็น hex หรือไม่? นอกจากนี้วิธีที่คุณได้รับตัวอย่างที่สอง7ดูเหมือนกับดัชนี zero-based และeเป็นดัชนีแบบใช้ครั้งเดียว ( e-7=7แต่มีรหัสฐานสิบหก 8 ในผลลัพธ์ของคุณ), หรือฉันมองอะไร
Neil

คำตอบ:


5

05AB1E , 39 38 ไบต์

ป้อนข้อมูลในแบบฟอร์ม:

arg2
arg3
arg1

รหัส:

²\|vy9F¦}40£ðK}J2ô„\xì²H>²®Qi²}£¹HF¦}J

คำอธิบาย:

²\                                       # Get the first two inputs and discard them.
  |                                      # Take the rest of the input as an array.
   vy         }                          # For each line...
     9F¦}                                #   Ten times, remove the first character.
         40£                             #   Only remain the substring [0:40].
            ðK                           #   Remove spaces.
               J                         # Join the string.
                2ô                       # Split into pieces of 2.
                  „\xì                   # Prepend a "\x" at each string.
                      ²H                 # Convert the second line from hex to int.
                        >                # Increment by one.
                         ²               # Push the second input again.
                          ®Qi }          # If equal to -1...
                             ²           #   Push the second input again.
                               £         # Take the substring [0:(² + 1)].
                                ¹H       # Convert the first input from hex to int.
                                  F¦}    # Remove that many characters at the beginning.
                                     J   # Join the array and implicitly output.

ใช้การเข้ารหัสCP-1252 ลองออนไลน์! .


12

Bash + coreutils + xxd, 73 71 69 ไบต์

printf \\x%s `xxd -r|xxd -p -s0x$1 -l$[(e=1+0x$2)?e-0x$1:-1]|fold -2`

คาดหวัง hexdump บน STDIN และเริ่มต้น / สิ้นสุดเป็นอาร์กิวเมนต์บรรทัดคำสั่ง

สิ่งนี้จะพิมพ์คำเตือนไปที่ STDERR ซึ่งได้รับอนุญาตโดยค่าเริ่มต้น


1
ฉันหวังว่าจะมีคนใช้xxdโซลูชันของพวกเขาจริง ๆ!
addison

@addison ฉันพยายาม แต่ lang ของฉันไม่สนับสนุนบรรทัดใหม่ในอินพุต commandline : c
Addison Crump

ฉันสามารถแทนที่16#ด้วย0x?
Digital Trauma

@ DigitalTrauma ฉันคิดว่ามันเป็นxxdสิ่ง แต่ดูเหมือนว่าจะทำงานได้ทุกที่
เดนนิส

1
ใช่ทุบตีแยกวิเคราะห์0xnรูปแบบหกเหลี่ยมและ0mรูปแบบตัวเลขฐานแปดออกจากกล่อง: gnu.org/software/bash/manual/bash.html#Shell-Arithmetic echo $[0x2a] $[052].
บาดเจ็บทางดิจิทัล

5

JavaScript, 84 ไบต์

(s,f,t,u)=>s.replace(/.*:|  .*\n?| /g,'').replace(/../g,'\\x$&').slice(f*4,++t*4||u)

คำอธิบาย: ลบส่วนที่ไม่ต้องการทั้งหมดของดัมพ์\xนำหน้าแต่ละคู่ฐานสิบหกจากนั้นแยกส่วนของผลลัพธ์ที่ต้องการ ||uใช้ในการแปลงค่าศูนย์ที่ได้รับโดยการเพิ่ม-1พารามิเตอร์undefinedซึ่งเป็นค่าเวทย์มนตร์ที่ทำให้sliceชิ้นส่วนท้ายของสตริง 101 ไบต์ถ้าfและtเป็นสตริงของเลขฐานสิบหก:

(s,f,t,u)=>s.replace(/.*:|  .*\n?| /g,``).replace(/../g,`\\x$&`).slice(`0x${f}`*4,t<0?u:`0x${t}`*4+4)

แทนที่จะ(s,f,t,u)=>ทำเช่นนั้นคุณสามารถทำได้s=>f=>t=>u=>เพื่อบันทึกสองสามไบต์
Ismael Miguel

@IsmaelMiguel ขออภัยที่ใช้ได้เฉพาะฟังก์ชันที่มีพารามิเตอร์จริงสองตัวเท่านั้น ในกรณีเฉพาะของฉันuต้องเป็นพารามิเตอร์เพิ่มเติมและไม่สามารถ curated
Neil

@IsmaelMiguel อีกต่อไปแล้วที่จริงแล้วอีกต่อไป ...
Jakob

5

ทับทิม: 90 89 87 79 63 ไบต์

-2 ไบต์ต้องขอบคุณ @addison
-8 ไบต์ต้องขอบคุณ @PiersMainwaring

->s,x,y{'\x'+s.scan(/(?<=.{9})\w\w(?=.* )/)[x.hex..y.hex]*'\x'}

ดูการทดสอบ repl.it: https://repl.it/Cknc/5


คุณสามารถแทนที่.joinด้วย*""เพื่อบันทึก 2 ไบต์
addison

คุณสามารถแทนที่.map{|h|h.to_i(16)}ด้วย.map(&:hex)เพื่อบันทึกอีก 8 ไบต์!
piersadrian

ขอบคุณ @PierMainwaring! โง่ของฉันที่จะลืมว่า อันที่จริงมันช่วยฉัน 16 เพราะมันสั้นกว่าที่จะเรียก.hexข้อโต้แย้งทีละคน!
จอร์แดน

4

เจลลี่ , 48 44 ไบต์

ØhiЀɠ’ḅ¥®L’¤Ạ?⁴‘
ṣ⁷ṫ€⁵ḣ€40Fḟ⁶s©2ḣ¢ṫ¢[“\x”]p

สิ่งนี้คาดว่า hexdump เป็นอาร์กิวเมนต์บรรทัดคำสั่ง แต่เพียงผู้เดียวและจุดสิ้นสุดและจุดเริ่มต้นบน STDIN ตามลำดับนั้นคั่นด้วย linefeed

ลองออนไลน์!


ฉันชอบที่จะดูคำอธิบายนี้;)
Conor โอไบรอัน

ฉันจะเพิ่มทีหลัง แต่ฉันจะพยายามตีกอล์ฟก่อน 51 bytes of Jelly เทียบกับ 69 bytes of Bash ไม่ถูกต้อง ...
Dennis

3

PowerShell v2 +, 175 157 142 133 129 ไบต์

param($a,$b,$c)'\x'+(($z=$a-split"`n"|%{$_[10..48]-ne32-join''-split'(..)'-ne''})["0x$b"..(("0x$c",$z.count)[$c-eq-1])]-join'\x')

จะเข้า$a, $b, $cมี$aเป็นทั้งสตริงขึ้นบรรทัดใหม่แยกตัวอักษรหรือด้วย PowerShell`nตัวอักษรแยกสาย เราตั้งค่าสตริงผู้ช่วย$zเป็นประมวลผลอย่างมาก$aดังนี้ -

ก่อนอื่นเรา-splitขึ้นบรรทัดใหม่แล้วสำหรับแต่ละบรรทัด|%{...}เราแบ่งส่วนตรงกลาง[10..48]ใช้-ne32เพื่อลบช่องว่าง-joinมันรวมเข้าด้วยกันเป็นสตริงยาวหนึ่งเส้น-splitมันในทุกตัวละครสองตัว (การรักษาตัวละครสองตัว) และ-ne''ในการลบองค์ประกอบที่ว่างเปล่า ('31','c0','b0'...)ผลนี้ในอาร์เรย์ของสตริงสององค์ประกอบเช่น

จากนั้นเราจะหั่นเป็น array ว่าขึ้นอยู่กับนักแสดงกับผู้ประกอบการเลขฐานสิบหกถึงค่าของ$b $cเราจำเป็นต้องใช้นามแฝงปลอมที่นี่เพื่อพิจารณาว่า$cเป็น-1หรือไม่ หากเป็นเช่นนั้นเราเลือก.count(เช่นองค์ประกอบสุดท้าย) ของ$zของ มิฉะนั้นเราเพิ่งเติมตัว0xดำเนินการฐานสิบหกด้วย$cในสตริง โปรดทราบว่านี่เป็นดัชนีที่ไม่มีศูนย์

ชิ้นส่วนของอาร์เรย์นั้นมีองค์ประกอบที่ถูก-joinรวมเข้ากับตัวอักษร\xในรูปแบบหนึ่งสตริง นั่นเป็นสิ่งที่ถูกเตรียมไว้ด้วยตัวอักษรอื่น\xและผลลัพธ์จะถูกทิ้งไว้ที่ท่อ การพิมพ์โดยปริยาย

ตัวอย่าง

PS C:\Tools\Scripts\golfing> .\xxd-output.ps1 "00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY" a -1
\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e\x58\x58\x58\x58\x59\x59\x59\x59

คุณสามารถเข้าถึงเชลล์ด้วยภาษานี้ได้หรือไม่?
Addison Crump

@VTCAKAVSMoACE ตามทฤษฎีแล้วเนื่องจากระบบย่อย Windowsใหม่สำหรับ Linuxมันเป็นไปได้ที่จะรวมสิ่งต่าง ๆ เข้าด้วยกันและ / หรือผ่านพารามิเตอร์ผ่านทางบรรทัดคำสั่ง การใช้งานที่เหลือเป็นแบบฝึกหัดสำหรับผู้อ่าน ;-)
AdmBorkBork

2

เจลลี่ , 39 38 37 ไบต์

ØhiⱮɠ’ḅ¥ȷ9Ṃ?⁴‘
Ỵṫ€⁵ḣ€40Fḟ⁶s2ṭ€⁾\xḣ¢ṫ¢

ลองออนไลน์!

ตอนนี้เต้น 05AB1E! (แม้จะไม่มี "แปลงจากเลขฐานสิบหก" builtin)

รูปแบบอินพุตเดียวกันเป็น วิธีการแก้ปัญหาของเดนนิส

ใช้ซึ่งเป็นคุณสมบัติใหม่ (ย่อมาจากЀ) หากไม่มีมันจะใช้เวลา 38 ไบต์


ใช้งานได้กับอินพุตที่มีความยาวสูงสุด 1e9 เท่านั้น
user202729

แต่ถ้ามันอยู่ใน FAT32 (ที่ขนาดอินพุตสูงสุด 2GB) ก็เพียงพอแล้ว
user202729

1

Perl, 114 ไบต์

($_,$a,$b)=@ARGV;s/^.*:|\S*$|\s//gm;@_=(m/../g);for(@_){s/^/\\x/}$"='';say substr"@_",4*$a,$b!=-1?4*($a+$b):2<<20;

อาร์กิวเมนต์ที่กำหนดในบรรทัดคำสั่งเป็นสตริงที่ยกมาแล้วตามด้วยตัวเลขสองตัว ตัวเลขถูกใช้เป็นทศนิยม (ฉันรู้ว่าเลขฐานสิบหกถูกใช้ในตัวอย่าง แต่ไม่ได้ระบุในโพสต์)

ในทางเทคนิคใช้งานได้กับอินพุตที่มีขนาดสูงสุด 2 ^ 21 ไบต์เท่านั้นเนื่องจากวิธีการย่อยของ perl นั้นโง่


เห็นได้ชัดว่าช่วงนั้นได้รวมดังนั้นสำหรับตัวอย่างเช่น7การeจะส่งผลให้ในสตริงของความยาว 32.
นีล

1

Python ขนาด 140 ไบต์

lambda O,a,b:''.join(sum([['\\x'+x[:2],('','\\x')[len(x)>2]+x[2:]]for x in O.split()if len(x)<5],[])[int(a,16):(int(b,16)+1,None)[b=='-1']])

https://repl.it/ClB3

แยกสตริงเดิมและดัมพ์องค์ประกอบหากมีอักขระน้อยกว่าห้าตัวการเตรียมการ\xและการแบ่งส่วนตามอาร์กิวเมนต์ที่สองและสาม

162 byte version หากเราต้องการจัดการกับ output ประเภทอื่นที่ไม่ได้ระบุโดยคำถาม:

import re
J=''.join
def f(x,a,b):r=J(J(re.findall(':(.*?)  ',x)).split());print J(['\\x'+i+j for i,j in zip(r,r[1:])][::2][int(a,16):(int(b,16)+1,None)[b=='-1']])

นี้จะไม่ทำงานถ้าเช่นบรรทัดสุดท้ายเป็นสิ่งที่ต้องการเพราะมันจะดึงออกมาจากส่วนที่ผ่านมาและคุณจะได้รับสิ่งที่ต้องการ00000030: 5858 58 XXX \x58\x58\x58\xXX\xX
AdmBorkBork

@ TimmyD ฉันไม่คิดว่าจะต้องจัดการกรณีนี้ให้ปิดสเปคของความท้าทาย
โบราณคดี

ฉันอ่านความท้าทายเนื่องจากอาร์กิวเมนต์แรกที่กำหนดเป็นเพียงตัวอย่างดังนั้นอาจมีxxdเอาต์พุตอื่นที่ใช้เป็นอาร์กิวเมนต์แทน "นี่คือตัวอย่างของรูปแบบของอาร์กิวเมนต์แรก:"
AdmBorkBork

0

Python 2 และ 3 - 164 162 150 146 134 150 ไบต์

ตอนนี้ยอมรับสตริง hex สำหรับอาร์กิวเมนต์ที่สองและสาม

j=''.join
def f(a,b,c):s=j(x[10:49].replace(' ','')for x in a.split('\n'));print(j('\\x'+s[i:i+2]for i in range(int(b,16)*2,1+2*int(c,16)%len(s),2))

0

Python 3.5, 125 ไบต์

import re
lambda s,b,e:re.sub(r'(\w\w)',r'\\x\1',re.sub(r'^.*?:|  .*$|\s','',s,0,8)[2*int(b,16):[2*int(e,16)+2,None][e<'0']])

Ungolfed:

def f(s,b,e):
    b = 2*int(b,16)
    e = [2*int(e,16)+2,None][e<'0']
    x = re.sub(r'''(?v)   # verbose (not in golfed version)
            ^.*?:     # match begining of line to the ':'
           |  .*$     # or match '  ' to end of line
           |\s        # or match whitespace
           ''',
           '',        # replacement
           s,
           0,         # replace all matches 
           re.M       # multiline mode
           )
    y = re.sub(r'(\w\w)', # match pairs of 'word' characters
           r'\\x\1',  # insert \x
            x[b:e])
    return y
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.