{
	"id": "2aa36f04-91b2-4372-90cf-b74a77f6b30c",
	"created_at": "2026-04-06T00:21:50.203462Z",
	"updated_at": "2026-04-10T13:11:46.035009Z",
	"deleted_at": null,
	"sha1_hash": "1911ee87ab306f8f82ab46d101fdc521ca99f0f0",
	"title": "Lobshot",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 76951,
	"plain_text": "Lobshot\r\nPublished: 2023-07-16 · Archived: 2026-04-05 21:16:26 UTC\r\nBackground\r\nReferences\r\nSamples\r\nAnalysis\r\nDarkVNC Overlap\r\nC2 Request\r\nConfig Extractor\r\nNotes\r\nBackground\r\nLOBSHOT is the internal name given to an hVNC based bot by the Elastic Security Labs team. The public name\r\nof this malware is currently unknown. The primary capability of the malware is acting as both a stealer and hidden\r\nVNC.\r\nReferences\r\nElastic Security Labs discovers the LOBSHOT malware\r\nSamples\r\ne4ea88887753a936eaf3361dcc00380b88b0c210dcbde24f8f7ce27991856bf6\r\nAnalysis\r\nDarkVNC Overlap\r\nOn VT the sample is being flagged as \"DarkVNC\" by Kaspersy this is possibly just an overlap with hVNC code\r\nfrom DarkVNC.\r\nC2 Request\r\nAccording to Elastic the C2 request contains some hardcoded data that can be used as a signature to hunt for the\r\nsamples.\r\nSearching for the above mov instruction paired with the first DWORD of the hardcoded value (C7 06\r\n25 56 0A DC) shows over 550 samples in VirusTotal within the last year. With some of the first samples\r\nshowing up in late July 2022. The prevalence of these hardcoded values shows that it has been actively\r\nused and under development for a long period of time, and will likely continue to be used in the future.\r\nhttps://research.openanalysis.net/lobshot/bot/hvnc/triage/2023/07/16/lobshot.html\r\nPage 1 of 6\n\nThere appears to also be a version number at the top of this struct\r\nThis has been copied from the original Elastic Github\r\n# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under\r\n# one or more contributor license agreements. Licensed under the Elastic License 2.0;\r\n# you may not use this file except in compliance with the Elastic License 2.0.\r\nNotes\r\nThe original sample used a convoluted way to obtain a static seed value used for the string decryption in\r\nother versions they realized this was silly and just hard coded a value\r\nThere are different seed values for different variants\r\nimport pefile\r\nimport re\r\nIP_ADDRESS_REGEX = r\"^([0-9]{1,3}\\.){3}[0-9]{1,3}$\"\r\nPORT_REGEX = r\"^[0-9]{1,5}$\"\r\ndef is_ascii(s):\r\n return all((c \u003c 128 and c \u003e 39) for c in s)\r\ndef perform_extraction_file(file_path):\r\n rdata = parse_file(file_path)\r\n if not rdata:\r\n raise RuntimeError(\".rdata section not found\")\r\n candidates = generate_candidates(rdata)\r\n strings = get_encrypted_strings(candidates)\r\n #print(strings)\r\n for s in strings:\r\n if re.search(IP_ADDRESS_REGEX, s):\r\nhttps://research.openanalysis.net/lobshot/bot/hvnc/triage/2023/07/16/lobshot.html\r\nPage 2 of 6\n\nresult_ip = s\r\n if re.search(PORT_REGEX, s):\r\n result_port = int(s)\r\n if not result_ip:\r\n raise RuntimeError(\"Configuration unsuccessful, could not extract IP/Port \\n\")\r\n print(f\"{result_ip}:{result_port}\")\r\ndef string_decryption(encrypted_data, seed):\r\n buffer = bytearray([0 for _ in range(len(encrypted_data) // 2)])\r\n flag = False\r\n z = 0\r\n index = 0\r\n index2 = 2\r\n for i, x in enumerate(encrypted_data):\r\n try:\r\n y = encrypted_data[index + 1] - 0x61\r\n index += 2\r\n if flag:\r\n buffer[i] = seed ^ z ^ (y | (16 * encrypted_data[index2] - 16)) \u0026 0xFF\r\n index2 += 2\r\n else:\r\n flag = True\r\n z = y | (16 * (x - 1)) \u0026 0xFF\r\n except (IndexError, ValueError):\r\n continue\r\n buffer = buffer[1:]\r\n return buffer\r\ndef parse_file(file_path):\r\n with open(file_path, \"rb\") as data:\r\n data = data.read()\r\n pe = pefile.PE(data=data)\r\n for section in pe.sections:\r\n if b\"rdata\" in section.Name:\r\n rdata = section.get_data()\r\n return rdata\r\n else:\r\n print(\".rdata section not found in {}\\n\".format(file_path.name))\r\n return None\r\nhttps://research.openanalysis.net/lobshot/bot/hvnc/triage/2023/07/16/lobshot.html\r\nPage 3 of 6\n\ndef generate_candidates(section_data):\r\n candidates: list[bytes] = list()\r\n blocks = section_data.split(b\"\\x00\")\r\n blocks = [x for x in blocks if x != b\"\"]\r\n for block in blocks:\r\n if len(block) \u003e 3 and not b\"\\\\\" in block:\r\n candidates.append(block)\r\n return candidates\r\ndef get_encrypted_strings(candidates):\r\n string_table = []\r\n seeds = 'abcdefghijklmnopqrstuvwxyz'\r\n seeds += seeds.upper()\r\n for s in seeds:\r\n seed = ord(s)\r\n tmp_out = []\r\n for string in candidates:\r\n decrypted_string = string_decryption(string, seed)\r\n decrypted_string = decrypted_string.replace(b'\\x00', b'')\r\n if len(decrypted_string) \u003c 3 or not is_ascii(decrypted_string):\r\n continue\r\n tmp_out.append(decrypted_string.decode('utf-8'))\r\n if 'connect' in tmp_out or 'msedge.exe' in tmp_out or 'kernel32.dll' in tmp_out:\r\n string_table = tmp_out\r\n break\r\n return string_table\r\ndef decrypt_candidates(candidates):\r\n result_ip = None\r\n result_port = None\r\n for string in candidates:\r\n decrypted_string = string_decryption(string, ord('S'))\r\n print(decrypted_string)\r\n if re.search(IP_ADDRESS_REGEX, decrypted_string):\r\n result_ip = decrypted_string\r\n if re.search(PORT_REGEX, decrypted_string):\r\n result_port = int(decrypted_string)\r\n if not result_ip:\r\n raise RuntimeError(\"Configuration unsuccessful, could not extract IP/Port \\n\")\r\n return result_ip.decode('utf-8'), result_port\r\ndef display_results(result):\r\n print(\"FILE: {}\".format(result[2].name))\r\nhttps://research.openanalysis.net/lobshot/bot/hvnc/triage/2023/07/16/lobshot.html\r\nPage 4 of 6\n\nprint(\"IP: {}\".format(result[0].decode(\"utf-8\")))\r\n print(\"Port: {}\\n\".format(result[1]))\r\nFILE_PATH = '/tmp/e4ea88887753a936eaf3361dcc00380b88b0c210dcbde24f8f7ce27991856bf6'\r\nperform_extraction_file(FILE_PATH)\r\n95.217.125.200:443\r\nchr(0x53)\r\n'S'\r\nimport os\r\n# assign directory\r\ndirectory = '/tmp/lobshots'\r\n \r\n# iterate over files in\r\n# that directory\r\nfor filename in os.listdir(directory):\r\n f = os.path.join(directory, filename)\r\n # checking if it is a file\r\n if os.path.isfile(f):\r\n try:\r\n print(f)\r\n perform_extraction_file(f)\r\n except:\r\n print('\\t fail!')\r\n/tmp/lobshots/1560ff3abacb50dc796f76eada2f8d8c020fa3e4a1f57b806029f44fca5682ae\r\n193.149.176.112:443\r\n/tmp/lobshots/b937eb4c88479119655b956f5be7e96c87fee72fa1d705028fe915719c7e8718\r\n168.100.10.88:443\r\n/tmp/lobshots/e14ee6302076a2bb9e5634407500757319d5de9c45305ec6269120b7283b24cf\r\n64.190.113.123:443\r\n/tmp/lobshots/7195799e2783d90b4f1ab326207c286064ca3557eb68a0dd04e65760781ba6bf\r\n64.52.80.210:443\r\n/tmp/lobshots/92dc319c346eccbffd091e87aef346751bf2af21d104010f1658639d7cd7b09f\r\n64.52.80.210:443\r\n/tmp/lobshots/61221cd73093dc61d224f979b680433d33f4cca6e14be6a79d71028b778d3668\r\n64.52.80.210:443\r\n/tmp/lobshots/0100d00ec16886288a5acd559dc055052578a607a265eaa3bf349c1140a00489\r\n64.52.80.210:443\r\nhttps://research.openanalysis.net/lobshot/bot/hvnc/triage/2023/07/16/lobshot.html\r\nPage 5 of 6\n\n/tmp/lobshots/2db2248ee80a26252576c2463f11ced5e6fa855cb8a5c929af135f45d9fbd862\r\n146.70.86.228:443\r\n/tmp/lobshots/88502f27ab03c34af7ceda2bb6fecda42ae227e74e8a5e52346db749e200d134\r\n91.235.136.155:443\r\n/tmp/lobshots/48f61315302ba4cac52f949a173981982d22bebc367866b929461f19738927d9\r\n64.52.80.210:443\r\n/tmp/lobshots/8cbae065a70d589fb78723a2c7dc5e903694196b82cea9ee7a53bac9750d5ad1\r\n64.52.80.210:443\r\n/tmp/lobshots/5532ea44f1f30f2e8a36e8d0ab5da7f9f5bfb15cd25a5100b8810490a2482039\r\n66.85.74.142:443\r\n/tmp/lobshots/8309535e526cf7eab791082b6f1ae6961739d2826779f9e920c3ed684c6a28f1\r\n179.43.162.5:443\r\n/tmp/lobshots/85364b9503ec20a8801bfd20db136c072d4ab7506f8afca81faf4b72567ee43d\r\n64.190.113.123:443\r\n/tmp/lobshots/77767acf212e727f9c1c9a07535980ce37d6e9a2c1431cfde81bf3d9eaf6fb05\r\n64.190.113.123:443\r\n/tmp/lobshots/ae221670729038f92398b7fe4e08928ea6ebc0c1d006c63c8a3bac2e30770c2b\r\n77.91.84.186:443\r\n/tmp/lobshots/7e0e7def3be7f9bc7793bf155935d16a9db631dd99b71ab51295338315129cce\r\n64.190.113.123:443\r\n/tmp/lobshots/921db56e4de5605b3759de43727f62be0f4c158a2837cf08ff376c427b85bec8\r\n193.149.180.212:443\r\n/tmp/lobshots/2c89fb34f8dd0094d988bd5460596141209e2b6afc15ef0288d8128cad70cc2e\r\n91.103.252.54:443\r\n/tmp/lobshots/17291fc45dc342a6ce4309dd4b77cd094c564fad14c212bca827770daf7207d4\r\n64.52.80.210:443\r\n/tmp/lobshots/15ec54cd2b2605ec8395645fe545204a89ddfe6fef656c98c0578006184d0228\r\n168.100.8.124:443\r\n/tmp/lobshots/22011ef253be77a08e930c391e61afd9234435216d3ff451b71834661e4858ed\r\n45.61.136.124:443\r\n/tmp/lobshots/e4ea88887753a936eaf3361dcc00380b88b0c210dcbde24f8f7ce27991856bf6\r\n95.217.125.200:443\r\n/tmp/lobshots/5ab55b3fb492e568db48cd0eac2770621d99f1f72cfe317f6601cd2447074b4f\r\n193.149.176.112:443\r\n/tmp/lobshots/209270bcd107207466f516789d4bfe677694cda5614e4abebaa26f2a827b293c\r\n146.70.86.228:443\r\nSource: https://research.openanalysis.net/lobshot/bot/hvnc/triage/2023/07/16/lobshot.html\r\nhttps://research.openanalysis.net/lobshot/bot/hvnc/triage/2023/07/16/lobshot.html\r\nPage 6 of 6",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://research.openanalysis.net/lobshot/bot/hvnc/triage/2023/07/16/lobshot.html"
	],
	"report_names": [
		"lobshot.html"
	],
	"threat_actors": [],
	"ts_created_at": 1775434910,
	"ts_updated_at": 1775826706,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/1911ee87ab306f8f82ab46d101fdc521ca99f0f0.pdf",
		"text": "https://archive.orkl.eu/1911ee87ab306f8f82ab46d101fdc521ca99f0f0.txt",
		"img": "https://archive.orkl.eu/1911ee87ab306f8f82ab46d101fdc521ca99f0f0.jpg"
	}
}