从arl中学习到的nmap配置

灯塔(ARL)里面有一个namp扫描模块,里面有配置可以学习一下 首先上代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 class PortScan: def __init__(self, targets, ports=None, service_detect=False, os_detect=False, port_parallelism=None, port_min_rate=None, custom_host_timeout=None): self.targets = " ".join(targets) self.ports = ports self.max_hostgroup = 128 self.alive_port = "22,80,443,843,3389,8007-8011,8443,9090,8080-8091,8093,8099,5000-5004,2222,3306,1433,21,25" self.nmap_arguments = "-sT -n --open" self.max_retries = 3 self.host_timeout = 60*5 self.parallelism = port_parallelism # 默认 32 self.min_rate = port_min_rate # 默认64 if service_detect: self.host_timeout += 60 * 5 self.nmap_arguments += " -sV" if os_detect: self.host_timeout += 60 * 4 self.nmap_arguments += " -O" if len(self.ports.split(",")) > 60: self.nmap_arguments += " -PE -PS{}".format(self.alive_port) self.max_retries = 2 else: if self.ports != "0-65535": self.nmap_arguments += " -Pn" if self.ports == "0-65535": self.max_hostgroup = 8 self.min_rate = max(self.min_rate, 400) self.nmap_arguments += " -PE -PS{}".format(self.alive_port) self.host_timeout += 60 * 2 self.max_retries = 2 self.nmap_arguments += " --max-rtt-timeout 800ms" self.nmap_arguments += " --min-rate {}".format(self.min_rate) self.nmap_arguments += " --script-timeout 6s" self.nmap_arguments += " --max-hostgroup {}".format(self.max_hostgroup) # 依据传过来的超时为准 if custom_host_timeout is not None: if int(custom_host_timeout) > 0: self.host_timeout = custom_host_timeout self.nmap_arguments += " --host-timeout {}s".format(self.host_timeout) self.nmap_arguments += " --min-parallelism {}".format(self.parallelism) self.nmap_arguments += " --max-retries {}".format(self.max_retries) def run(self): logger.info("nmap target {} ports {} arguments {}".format( self.targets[:20], self.ports[:20], self.nmap_arguments)) nm = nmap.PortScanner() nm.scan(hosts=self.targets, ports=self.ports, arguments=self.nmap_arguments) ip_info_list = [] for host in nm.all_hosts(): port_info_list = [] for proto in nm[host].all_protocols(): port_len = len(nm[host][proto]) for port in nm[host][proto]: # 对于开了很多端口的直接丢弃 if port_len > 600 and (port not in [80, 443]): continue port_info = nm[host][proto][port] item = { "port_id": port, "service_name": port_info["name"], "version": port_info["version"], "product": port_info["product"], "protocol": proto } port_info_list.append(item) osmatch_list = nm[host].get("osmatch", []) os_info = self.os_match_by_accuracy(osmatch_list) ip_info = { "ip": host, "port_info": port_info_list, "os_info": os_info } ip_info_list.append(ip_info) return ip_info_list def os_match_by_accuracy(self, os_match_list): for os_match in os_match_list: accuracy = os_match.get('accuracy', '0') if int(accuracy) > 90: return os_match return {} 入口是run ...

四月 13, 2022 · 3 分钟 · 

将Shikata ga nai带到前端

Shikata ga nai是什么 Metasploit-Framework是一个漏洞利用框架,里面有大量的漏洞库,针对shellcode一些混淆编码器可以让用户bypass一些安全软件,其中一个比较核心的编码器是Shikata Ga Nai (SGN)。 shellcode 主要是机器码,也可以看作一段汇编指令。Metasploit 在默认配置下就会对payload进行编码。虽然 Metasploit 有各种编码器,但最受欢迎的是 SGN。日语中的短语 SGN 的意思是“无能为力”,之所以这样说,是因为它在创建时传统的反病毒产品难以检测。 检测 SGN 编码的payload很困难,尤其是在严重依赖静态检测的情况下。任何基于规则的静态检测机制基本上都无法检测到用 SGN 编码的payload。而不断扫描内存的计算成本很高,因此不太可行。这使得大多数杀软依赖于行为指标和沙箱进行检测。 为什么说带到前端 首先介绍下 EgeBalci/sgn,这个项目将msf的Shikata Ga Nai编码器移植到了Golang,使得用户可以不通过msf即可享受到SGN的能力。 既然这个项目是非平台依赖的工具,那我们可以考虑将它移植到前端,这样用户只需要打开浏览器就能用了。 移植思路 首先我们可以考虑:sgn是一个golang项目,所以我们可以编译到wasm,然后暴露api给javascript来调用,这样就可以实现前端使用sgn了。 但是遇到了一些问题。 该项目并不是一个Pure Go项目,它依赖cgo,没办法编译到wasm。 但是我记得 github.com/therecipe/qt 可以编译到wasm,通过一些研究,发现它是采用了go-js-qt的桥接,qt是可以编译到wasm的,go也可以编译到wasm,然后两者之间再桥接起来。那我们可以尝试先将 github.com/keystone-engine/keystone 编译到wasm,然后将sgn项目里面调用cgo的地方全部使用 syscall/js 桥接到keystone上去,此时sgn变成了一个Pure Go项目,可以将其编译到wasm了,然后再暴露出一个接口就可以供js使用了 实现手段 cgo到桥接 sgn里面需要使用cgo是因为依赖 github.com/EgeBalci/keystone-go,看了一下这个项目,其实是keystone的包装,keystone是一个c++写的项目,所以我们可以考虑使用 emscripten 来将keystone编译到wasm,不过该项工作已经有人做了,我们在这边就不自己再花时间搭环境编译了,可以看看 alexaltea.github.io/keystone.js/ 然后我们看看sgn里面依赖cgo的地方,主要是在 pkg/sgn.go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 package sgn import ( ... "github.com/EgeBalci/keystone-go" ) ... // Assemble assembes the given instructions // and return a byte array with a boolean value indicating wether the operation is successful or not func (encoder Encoder) Assemble(asm string) ([]byte, bool) { var mode keystone.Mode switch encoder.architecture { case 32: mode = keystone.MODE_32 case 64: mode = keystone.MODE_64 default: return nil, false } ks, err := keystone.New(keystone.ARCH_X86, mode) if err != nil { return nil, false } defer ks.Close() err = ks.Option(keystone.OPT_SYNTAX, keystone.OPT_SYNTAX_INTEL) if err != nil { return nil, false } //log.Println(asm) bin, _, ok := ks.Assemble(asm, 0) return bin, ok } // GetAssemblySize assembes the given instructions and returns the total instruction size // if assembly fails return value is -1 func (encoder Encoder) GetAssemblySize(asm string) int { var mode keystone.Mode switch encoder.architecture { case 32: mode = keystone.MODE_32 case 64: mode = keystone.MODE_64 default: return -1 } ks, err := keystone.New(keystone.ARCH_X86, mode) if err != nil { return -1 } defer ks.Close() err = ks.Option(keystone.OPT_SYNTAX, keystone.OPT_SYNTAX_INTEL) if err != nil { return -1 } //log.Println(asm) bin, _, ok := ks.Assemble(asm, 0) if !ok { return -1 } return len(bin) } ... 其实工作量并不大,只是需要把所有对 keystone-go 的调用换到keystone.js上即可。 ...

三月 4, 2022 · 5 分钟 ·