Chuyển đổi đầu ra xxd sang shellcode


15

Lấy một số đầu ra từ xxd và biến nó thành shellcode có thể sử dụng bằng tay không có gì thú vị, vì vậy công việc của bạn là tự động hóa quy trình.

Quy tắc

Nội dung gửi của bạn có thể là một hàm, lambda, script hoặc bất kỳ tương đương hợp lý nào. Bạn có thể in kết quả hoặc nếu bài đăng của bạn là hàm / lambda thì bạn cũng có thể trả lại.

Chương trình của bạn phải có ba đối số, đầu tiên là một chuỗi chứa đầu ra của xxd, được chạy không có đối số nào ngoài tên tệp, như thế này : xxd some_file. Dưới đây là một ví dụ về đối số đầu tiên sẽ như thế nào:

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

Bạn cần lấy phần giữa đó chứa các byte (8 cột đầu tiên sau :) và biến nó thành shellcode bằng cách xóa bất kỳ khoảng trắng nào, sau đó đặt một \xtrước mỗi byte.

Dưới đây là những gì đầu ra nên cho đầu vào ở trên (bỏ qua mọi đối số khác):

\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

Bạn có thể giả sử đối số đầu tiên sẽ luôn là đầu ra xxd hợp lệ, được chạy mà không có đối số nào ngoài tên tệp.

Đầu ra của bạn cũng phải là một chuỗi trong đó dấu gạch chéo ngược là dấu gạch chéo ngược theo nghĩa đen, không được sử dụng làm ký tự thoát. Vì vậy, khi tôi nói "\ x65", tôi không nói về byte 0x65 hay thậm chí là chữ "A". Trong mã, nó sẽ là chuỗi "\ x65".

Đối số thứ hai chỉ định vị trí trong đầu ra xxd, shellcode sẽ bắt đầu và thứ ba chỉ định nơi nó sẽ kết thúc. Nếu đối số thứ ba là -1, nó sẽ kết thúc ở cuối đầu ra xxd. Đối số thứ hai và thứ ba cũng sẽ luôn không âm, ngoại trừ khi đối số thứ ba là-1

Dưới đây là một số trường hợp thử nghiệm:

Luận điểm 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

Đối số 2 : 7, Đối số 3: e(đây là cả hai chuỗi đại diện cho số thập lục phân)

Đầu ra: \xc9\xcd\x80\xeb\x16\x5b\x31\xc0

Luận điểm 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

Đối số 2 : 0, Đối số 3:2e

Đầu ra: \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

Luận điểm 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

Đối số 2 : a, Đối số 3:-1

Đầu ra: \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

Mã có ít byte nhất sẽ thắng. Người chiến thắng sẽ được công bố trong bảy ngày, vào ngày 15 tháng 8 năm 2016 (nhưng các bài nộp sau đó vẫn được đánh giá cao).

Cập nhật

Xin chúc mừng @Adnan đã chiến thắng thử thách!


Chỉ cần làm rõ, các mục có thể trả về một chuỗi hoặc họ phải in nó?
Jordan

Trả về một chuỗi là tốt miễn là nó là một hàm, lambda hoặc một cái gì đó tương tự (tôi đã cập nhật các quy tắc để xác định rằng sau khi bạn yêu cầu).
addison

1
Chúng tôi cũng có thể trả lại mã ASCII thông thường khi mã có thể in được không? Ví dụ ~thay vì \x7e. Và chúng ta có thể trở lại \tthay vì \x09?
orlp

@orlp Xin lỗi không, nó cần phải ở một định dạng nhất quán.
addison

Các đối số được yêu cầu phải ở trong hex? Ngoài ra, cách bạn đưa ra ví dụ thứ hai, 7trông giống như một chỉ mục dựa trên số 0 và elà một chỉ mục dựa trên một ( e-7=7nhưng có 8 mã hex trong đầu ra của bạn), hoặc tôi đang xem xét điều gì?
Neil

Câu trả lời:


5

05AB1E , 39 38 byte

Nhập vào dưới dạng:

arg2
arg3
arg1

Mã số:

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

Giải trình:

²\                                       # 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.

Sử dụng mã hóa CP-1252 . Hãy thử trực tuyến! .


12

Bash + coreutils + xxd, 73 71 69 byte

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

Yêu cầu hexdump trên STDIN và bắt đầu / kết thúc dưới dạng đối số dòng lệnh.

Điều này in một số cảnh báo cho STDERR, được cho phép theo mặc định.


1
Tôi đã hy vọng ai đó thực sự sẽ sử dụng xxdtrong giải pháp của họ!
addison

@addison Tôi đã cố gắng, nhưng lang của tôi không hỗ trợ các dòng mới trong đầu vào dòng lệnh. : c
Addison Crump

Tôi có thể thay thế 16#bằng 0x?
Chấn thương kỹ thuật số

@DigitalTrauma Tôi nghĩ đó là một xxdthứ, nhưng nó dường như hoạt động ở mọi nơi.
Dennis

1
Có, bash phân tích cú pháp 0xnkiểu hex và số 0mbát phân ra khỏi hộp: gnu.org/software/bash/manual/bash.html#Shell-Arithatures . echo $[0x2a] $[052].
Chấn thương kỹ thuật số

5

JavaScript, 84 byte

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

Giải thích: Loại bỏ tất cả các phần không mong muốn của kết xuất, \xtrả trước cho mỗi cặp hex, sau đó trích xuất phần mong muốn của kết quả. ||uđược sử dụng để chuyển đổi số không thu được bằng cách tăng -1tham số thành undefinedgiá trị ma thuật gây ra slicelát cắt đến cuối chuỗi. 101 byte nếu ftlà các chuỗi chữ số hex:

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

Thay vì (s,f,t,u)=>, bạn có thể làm s=>f=>t=>u=>, để tiết kiệm một vài byte.
Ismael Miguel

@IsmaelMiguel Xin lỗi, chỉ hoạt động cho một hàm với chính xác hai tham số thực tế. Trong trường hợp cụ thể của tôi, đó uphải là một tham số bổ sung và không thể bị loại bỏ.
Neil

@IsmaelMiguel Ngoài ra, điều đó thực sự lâu hơn ...
Jakob

5

Ruby: 90 89 87 79 63 byte

-2 byte nhờ @addison
-8 byte nhờ @PiersMainwaring

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

Xem các bài kiểm tra trên repl.it: https://repl.it/Cknc/5


Bạn có thể thay thế .joinbằng *""để lưu 2 byte.
addison

Bạn có thể thay thế .map{|h|h.to_i(16)}bằng .map(&:hex)để tiết kiệm thêm 8 byte!
piersadrian

Cảm ơn @PiersMainwaring! Ngớ ngẩn của tôi để quên điều đó. Nó thực sự đã cứu tôi 16 vì hóa ra nó ngắn hơn để gọi.hex cho các đối số!
Jordan

4

Thạch , 48 44 byte

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

Điều này hy vọng hexdump là đối số dòng lệnh duy nhất và điểm kết thúc và điểm bắt đầu trên STDIN, theo thứ tự đó, được phân tách bằng một nguồn cấp dữ liệu.

Hãy thử trực tuyến!


Tôi rất muốn xem một lời giải thích cho điều này;)
Conor O'Brien

Tôi sẽ thêm một cái sau, nhưng tôi sẽ thử đánh gôn trước một chút. 51 byte Jelly so với 69 byte Bash không thể đúng ...
Dennis

3

PowerShell v2 +, 175 157 142 133 129 byte

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 đầu vào $a, $b, $c, với $anhư hoặc là một chuỗi xuống dòng được tách biệt theo nghĩa đen, hoặc với PowerShell `nnhân vật tách dòng. Chúng tôi đặt chuỗi trình trợ giúp $znhư được xử lý nhiều $anhư sau -

Đầu tiên chúng tôi -splittrên dòng mới, sau đó, với mỗi dòng |%{...}, chúng tôi cắt phần giữa [10..48], sử dụng -ne32để xóa khoảng trắng,-join nó lại với nhau thành một chuỗi dài, -splittrên mỗi hai ký tự (giữ hai ký tự) và -ne''để loại bỏ các phần tử trống. Điều này dẫn đến một chuỗi các chuỗi hai phần tử, như ('31','c0','b0'...).

Sau đó, chúng tôi cắt thành mảng đó dựa trên việc $btruyền với toán tử thập lục phân lên đến giá trị của $c. Chúng ta cần sử dụng một giả ba ở đây mà tài khoản cho dù $c-1hay không. Nếu có, chúng tôi chọn .count(tức là phần tử kết thúc) của$z . Mặt khác, chúng ta chỉ cần thêm 0xtoán tử thập lục phân $ctrong một chuỗi. Lưu ý rằng đây là chỉ số không.

Mảng đó có các phần tử của nó -join ed cùng với một chữ \xđể tạo thành một chuỗi. Điều đó được chuẩn bị với một nghĩa đen khác \xvà kết quả được để lại trên đường ống dẫn. In ấn là ngầm.

Thí dụ

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

Bạn có thể truy cập shell với ngôn ngữ này?
Addison Crump

@VTCAKAVSMoACE Về lý thuyết, với Hệ thống con Windows mới cho Linux , có thể kết nối mọi thứ lại với nhau và / hoặc truyền tham số qua dòng lệnh. Thực hiện được để lại như một bài tập cho người đọc. ;-)
admBorkBork

2

Thạch , 39 38 37 byte

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

Hãy thử trực tuyến!

Bây giờ nhịp 05AB1E! (mặc dù thiếu nội dung "chuyển đổi từ thập lục phân")

Định dạng đầu vào giống như giải pháp của Dennis .

Sử dụng , đó là một tính năng mới (viết tắt của Ѐ). Không có nó, điều này sẽ mất 38 byte.


Chỉ hoạt động cho đầu vào với len lên đến 1e9.
dùng202729

Nhưng nếu đó là trên FAT32 (trong đó kích thước đầu vào tối đa là 2 GB) thì đủ.
dùng202729

1

Perl, 114 byte

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

Các đối số được đưa ra trên dòng lệnh dưới dạng một chuỗi được trích dẫn theo sau bởi hai số. Các số được lấy theo số thập phân (tôi biết hex được sử dụng trong các ví dụ nhưng nó không được chỉ định trong bài)

Về mặt kỹ thuật chỉ hoạt động trên các đầu vào có tối đa 2 ^ 21 byte do phương thức chuỗi con của perl là ngớ ngẩn


Rõ ràng phạm vi là toàn diện, vì vậy ví dụ 7để enên kết quả trong một chuỗi có độ dài 32.
Neil

1

Python, 140 byte

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

Tách chuỗi gốc và loại bỏ các phần tử nếu chúng có ít hơn năm ký tự \x, các phần trước và các lát cắt bởi các đối số thứ hai và thứ ba.

Phiên bản 162 byte nếu chúng ta cần xử lý các loại đầu ra khác không được chỉ định bởi câu hỏi:

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']])

Điều này sẽ không hoạt động nếu, ví dụ, dòng cuối cùng là một cái gì đó giống như 00000030: 5858 58 XXXvì nó sẽ lấy ra phần cuối cùng và bạn sẽ nhận được một cái gì đó như thế \x58\x58\x58\xXX\xX.
admBorkBork

@TimmyD Tôi không nghĩ rằng trường hợp đó cần phải được xử lý, đi ra khỏi thông số kỹ thuật của thử thách.
đồ học

Tôi đọc thử thách vì đối số đầu tiên đã cho chỉ là một ví dụ, vì vậy có thể có xxdđầu ra khác được sử dụng làm đối số thay thế. "Đây là một ví dụ về đối số đầu tiên sẽ như thế nào:"
admBorkBork

0

Con trăn 2 và 3 - 164 162 150 146 134 150 byte

Bây giờ chấp nhận chuỗi hex cho đối số thứ hai và thứ ba.

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 byte

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']])

Ung dung:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.