Ubah output xxd ke shellcode

15

Mengambil beberapa output dari xxd dan mengubahnya menjadi shellcode yang dapat digunakan dengan tangan tidak menyenangkan, jadi tugas Anda adalah mengotomatiskan proses.

Aturan

Kiriman Anda dapat berupa fungsi, lambda, skrip, atau yang setara dengan itu. Anda dapat mencetak hasilnya, atau jika kiriman Anda adalah fungsi / lambda maka Anda juga dapat mengembalikannya.

Anda Program harus mengambil tiga argumen, yang pertama adalah string yang berisi output dari xxd, berlari tanpa argumen selain nama file, seperti ini: xxd some_file. Berikut ini contoh tampilan argumen pertama:

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

Anda perlu mengambil bagian tengah yang berisi byte (8 kolom pertama setelah :) dan mengubahnya menjadi shellcode dengan menghapus spasi, lalu meletakkan \xsebelum setiap byte.

Inilah yang seharusnya menjadi input untuk input di atas (mengabaikan argumen lain):

\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

Anda dapat mengasumsikan argumen pertama akan selalu berupa output xxd yang valid, dijalankan tanpa argumen selain nama file.

Output Anda juga harus berupa string di mana garis miring terbalik adalah garis miring terbalik literal, tidak digunakan sebagai karakter pelarian. Jadi ketika saya mengatakan "\ x65", saya tidak berbicara tentang byte 0x65, atau bahkan huruf "A". Dalam kode, itu adalah string "\ x65".

Argumen kedua menentukan di mana dalam output xxd shellcode harus dimulai, dan argumen ketiga menentukan di mana ia harus berakhir. Jika argumen ketiga adalah -1, itu akan berakhir pada akhir output xxd. Argumen kedua dan ketiga juga akan selalu non negatif, kecuali ketika argumen ketiga-1

Berikut ini beberapa kasus uji:

Argumen 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

Argumen 2 7:, Argumen 3: e(keduanya adalah string yang mewakili angka heksadesimal)

Keluaran: \xc9\xcd\x80\xeb\x16\x5b\x31\xc0

Argumen 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

Argumen 2 0:, Argumen 3:2e

Keluaran: \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

Argumen 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

Argumen 2 a:, Argumen 3:-1

Keluaran: \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

Kode dengan byte paling sedikit menang. Pemenang akan diumumkan dalam tujuh hari, pada 15 Agustus 2016 (tetapi pengiriman setelah itu masih dihargai).

Memperbarui

Selamat kepada @Adnan untuk memenangkan tantangan!

addison
sumber
Hanya untuk memperjelas, bisakah entri mengembalikan string atau haruskah mereka mencetaknya?
Jordan
Mengembalikan string baik-baik saja asalkan itu fungsi, lambda, atau sesuatu seperti itu (saya memperbarui aturan untuk menentukan itu setelah Anda bertanya).
addison
1
Bisakah kita juga mengembalikan kode ASCII biasa ketika kode itu dapat dicetak? Misalnya ~bukannya \x7e. Dan bisakah kita kembali, \tbukan \x09?
orlp
@ orlp Maaf tidak, harus dalam format yang konsisten.
addison
Apakah argumen harus dalam hex? Juga, cara Anda memberikan contoh kedua, 7terlihat seperti indeks berbasis nol dan emerupakan indeks berbasis satu ( e-7=7tetapi ada 8 kode hex pada output Anda), atau apakah saya mengabaikan sesuatu?
Neil

Jawaban:

5

05AB1E , 39 38 byte

Masukan dalam bentuk:

arg2
arg3
arg1

Kode:

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

Penjelasan:

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

Menggunakan pengkodean CP-1252 . Cobalah online! .

Adnan
sumber
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`

Harapkan hexdump pada STDIN dan mulai / akhiri sebagai argumen baris perintah.

Ini mencetak beberapa peringatan ke STDERR, yang diizinkan secara default.

Dennis
sumber
1
Saya berharap seseorang benar-benar akan menggunakan xxdsolusi mereka!
addison
@addison saya mencoba, tetapi bahasa saya tidak mendukung baris baru dalam input baris perintah. : c
Addison Crump
Saya bisa mengganti 16#dengan 0x?
Digital Trauma
@DigitalTrauma Saya pikir itu adalah xxdsesuatu, tetapi tampaknya berfungsi di mana-mana.
Dennis
1
Ya, bash mem-parsing 0xnheks gaya dan 0mangka gaya oktal di luar kotak: gnu.org/software/bash/manual/bash.html#Shell-Arithmetic . echo $[0x2a] $[052].
Digital Trauma
5

JavaScript, 84 byte

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

Penjelasan: Hapus semua bagian yang tidak diinginkan dari dump, tambahkan \xmasing-masing pasangan hex, kemudian ekstrak bagian yang diinginkan dari hasil. ||udigunakan untuk mengkonversi nol yang diperoleh dengan menambah -1parameter undefinedyang merupakan nilai ajaib yang menyebabkan sliceirisan ke ujung string. 101 byte jika fdan tadalah string digit hex:

(s,f,t,u)=>s.replace(/.*:|  .*\n?| /g,``).replace(/../g,`\\x$&`).slice(`0x${f}`*4,t<0?u:`0x${t}`*4+4)
Neil
sumber
Alih-alih (s,f,t,u)=>, Anda bisa melakukannya s=>f=>t=>u=>, untuk menyimpan beberapa byte.
Ismael Miguel
@ IsmaelMiguel Maaf, itu hanya berfungsi untuk fungsi dengan tepat dua parameter aktual. Dalam kasus khusus saya, uharus berupa parameter tambahan dan tidak dapat dijelajahi.
Neil
@IsmaelMiguel Juga itu sebenarnya lebih lama ...
Jakob
5

Ruby: 90 89 87 79 63 byte

-2 byte terima kasih kepada @addison
-8 byte terima kasih kepada @PiersMainwaring

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

Lihat tes di repl.it: https://repl.it/Cknc/5

Yordania
sumber
Anda dapat mengganti .joindengan *""untuk menyimpan 2 byte.
addison
Anda dapat mengganti .map{|h|h.to_i(16)}dengan .map(&:hex)untuk menyimpan 8 byte lebih banyak!
piersadrian
Terima kasih @PiersMainwaring! Bodoh bagi saya untuk melupakan itu. Ini sebenarnya menyelamatkan saya 16 karena ternyata lebih pendek untuk memanggil .hexargumen secara individual!
Jordan
4

Jelly , 48 44 byte

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

Ini mengharapkan hexdump sebagai argumen baris perintah tunggal, dan titik akhir dan mulai pada STDIN, dalam urutan itu, dipisahkan oleh linefeed.

Cobalah online!

Dennis
sumber
Saya ingin melihat penjelasan untuk ini;)
Conor O'Brien
Saya akan menambahkan satu nanti, tetapi saya akan mencoba golf sedikit dulu. 51 byte Jelly vs 69 byte Bash tidak mungkin benar ...
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')

Mengambil input $a, $b, $c, dengan $abaik sebagai baris baru-string dipisahkan literal, atau dengan PowerShell `nkarakter memisahkan baris. Kami menetapkan helper string $zsebagai sangat diproses $asebagai berikut -

Pertama kita -splitdi baris baru, lalu, untuk setiap baris |%{...}, kita mengiris bagian tengah [10..48], menggunakan -ne32untuk menghapus spasi, -joinkembali menjadi satu string panjang, -splitpada setiap dua karakter (menjaga dua karakter), dan -ne''untuk menghapus elemen kosong. Ini menghasilkan array string dua elemen, seperti ('31','c0','b0'...).

Kami kemudian mengiris array yang didasarkan pada $bgips dengan operator heksadesimal hingga nilai $c. Kita perlu menggunakan pseudo-ternary di sini yang menjelaskan apakah $citu benar -1atau tidak. Jika ya, kita memilih .count(yaitu, elemen akhir) dari $z. Jika tidak, kami hanya menambahkan 0xoperator heksadesimal $cdalam sebuah string. Perhatikan bahwa ini tidak diindeks.

Irisan array memiliki elemen-elemennya -joindisatukan dengan literal \xuntuk membentuk satu string. Itu diawali dengan literal lain \xdan hasilnya ditinggalkan di saluran pipa. Pencetakan tersirat.

Contoh

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
AdmBorkBork
sumber
Bisakah Anda mengakses shell dengan bahasa ini?
Addison Crump
@ VTCAKAVSMoACE Secara teori, mengingat Windows Subsystem baru untuk Linux , seharusnya dimungkinkan untuk menyatukan berbagai hal dan / atau melewatkan parameter melalui baris perintah. Implementasi dibiarkan sebagai latihan untuk pembaca. ;-)
AdmBorkBork
2

Jelly , 39 38 37 byte

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

Cobalah online!

Sekarang ketuk 05AB1E! (meskipun builtin "convert from hexadecimal")

Format input yang sama dengan solusi Dennis .

Gunakan , yang merupakan fitur baru (kependekan dari Ѐ). Tanpa itu, ini akan membutuhkan 38 byte.

pengguna202729
sumber
Hanya berfungsi untuk input dengan len hingga 1e9.
user202729
Tetapi jika itu pada FAT32 (di mana ukuran input paling banyak 2GB) sudah cukup.
user202729
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;

Argumen yang diberikan pada baris perintah sebagai string yang dikutip diikuti oleh dua angka. Angka diambil dalam desimal (saya tahu heks digunakan dalam contoh tetapi tidak ditentukan dalam pos)

Secara teknis hanya bekerja pada input dengan hingga 2 ^ 21 byte karena metode substring perl ini konyol

theLambGoat
sumber
Rupanya kisaran adalah inklusif, jadi misalnya 7untuk eharus menghasilkan serangkaian panjang 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

Pisahkan string asli dan buang elemen jika mereka kurang dari lima karakter, prepends \x, dan irisan dengan argumen kedua dan ketiga.

Versi 162 byte jika kita perlu menangani tipe output lain yang tidak ditentukan oleh pertanyaan:

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']])
ahli atlasologi
sumber
Ini tidak akan berfungsi jika, misalnya, baris terakhir adalah sesuatu 00000030: 5858 58 XXXkarena akan menarik bagian terakhir dan Anda akan mendapatkan sesuatu seperti \x58\x58\x58\xXX\xX.
AdmBorkBork
@TimmyD Saya tidak berpikir kasus itu perlu ditangani, pergi spesifikasi tantangan.
atlasologist
Saya membaca tantangan karena argumen pertama yang diberikan hanyalah sebuah contoh, jadi mungkin ada xxdoutput lain yang digunakan sebagai argumen. "Berikut adalah contoh dari bagaimana argumen pertama akan terlihat:"
AdmBorkBork
0

Python 2 dan 3 - 164 162 150 146 134 150 byte

Sekarang menerima string hex untuk argumen kedua dan ketiga.

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

Tidak Disatukan:

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
RootTwo
sumber