Перетворити xxd вихід у shellcode


15

Взяти певний вихід з xxd і перетворити його в корисний код оболонки вручну - це не цікаво, тому ваше завдання - автоматизувати процес.

Правила

Ваше подання може бути функцією, лямбда, сценарієм або будь-яким розумним еквівалентом. Ви можете надрукувати результат або якщо ваше подання є функцією / лямбда, то ви також можете повернути його.

Ви програма повинна приймати три аргументи, перший з яких рядок , що містить висновок 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 повинен починатися код оболонки, а третій визначає, де він повинен закінчуватися. Якщо третій аргумент -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 за перемогу у виклику!


Просто для уточнення, чи можуть записи повертати рядок чи вони повинні надрукувати його?
Йорданія

Повернення рядка добре, якщо це функція, лямбда чи щось подібне (я оновив правила, щоб вказати, що після того, як ви запитали).
аддісон

1
Чи можемо ми також повернути звичайні коди ASCII, коли код для друку? Наприклад, ~замість \x7e. І чи можемо ми повернутися \tзамість \x09?
orlp

@orlp Вибачте ні, це має бути у послідовному форматі.
Аддісон

Чи потрібні аргументи у шістнадцятковій формі? Крім того, те, як ви дали другий приклад, 7виглядає як нульовий індекс і eє одноосновним індексом ( e-7=7але у вашому виході є 8 шістнадцяткових кодів) чи я щось пропускаю?
Ніл

Відповіді:


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 та start / end як аргументи командного рядка.

Це друкує деякі попередження на STDERR, яке дозволено за замовчуванням.


1
Я сподівався, що хтось насправді використає xxdу своєму рішенні!
Аддісон

@addison Я намагався, але мій lang не підтримує нові рядки у введенні командного рядка. : c
Аддісон Кримп

Я можу замінити 16#з 0x?
Цифрова травма

@DigitalTrauma Я думав, що це xxdріч, але, здається, працює скрізь.
Денніс

1
Так, bash розбирає номери 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=>, щоб зберегти кілька байт.
Ісмаїл Мігель

@IsmaelMiguel Вибачте, що працює лише для функції з точно двома фактичними параметрами. У моєму конкретному випадку цей uобов'язок повинен бути додатковим параметром, і його не можна кривити.
Ніл

@IsmaelMiguel Також це насправді довше ...
Якоб

5

Ruby: 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 байти.
Аддісон

Ви можете замінити .map{|h|h.to_i(16)}з , .map(&:hex)щоб зберегти більше 8 байт!
пристань

Дякуємо @PiersMainwaring! Нерозумно мені це забути. Це насправді врятувало мене 16, тому що виявилося коротшим, щоб звертатися .hexдо аргументів окремо!
Йорданія

4

Желе , 48 44 байт

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

Це очікує, що hexdump буде єдиним аргументом командного рядка, а кінцеві та початкові точки на STDIN у такому порядку розділені рядковим записом.

Спробуйте в Інтернеті!


Я хотів би побачити пояснення цьому;)
Conor O'Brien

Я додам його пізніше, але спробую спочатку трохи пограти в гольф. 51 байт Jelly vs 69 байт 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'...).

Потім ми розрізаємо в цей масив на основі $bкадра з шістнадцятковим оператором до значення $c. Нам тут потрібно використовувати псевдотермінал, який пояснює, $cє -1чи ні. Якщо це так, ми вибираємо .count(тобто кінцевий елемент) $z. В іншому випадку ми просто додаємо 0xшістнадцятковий оператор до $cрядка. Зауважте, що це нульове значення.

У цьому фрагменті масиву є його елементи -joined разом із літералом, \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

Чи можете ви отримати доступ до оболонки з цією мовою?
Аддісон Кримп

@VTCAKAVSMoACE Теоретично, з огляду на нову підсистему Windows для Linux , слід створити об'єднання даних та / або передавати параметри за допомогою командного рядка. Реалізація залишається вправою для читача. ;-)
AdmBorkBork

2

Желе , 39 38 37 байт

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

Спробуйте в Інтернеті!

Тепер б'є 05AB1E! (незважаючи на відсутність вбудованого "перетворення з шістнадцяткової")

Той самий формат введення, що і рішення Денніса .

Використання , що є новою функцією (скорочено для Ѐ). Без цього це займе 38 байт.


Працює лише для введення з len до 1e9.
користувач202729

Але якщо він знаходиться на FAT32 (де розмір вводу становить не більше 2 Гб), цього достатньо.
користувач202729

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

Пітон, 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-байтна версія, якщо нам потрібно обробляти інші типи виводу, не визначені запитанням:

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 байт

Тепер приймає шістнадцяткові рядки для другого та третього аргументів.

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

Безголівки:

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.