mirror of
https://github.com/sairson/Yasso.git
synced 2026-02-13 23:35:17 +08:00
Yasso更新大改动,更新扫描方式,去除不常用功能,增加指纹和协议识别,修补bug等
This commit is contained in:
8
pkg/exploit/ldap/core/filter/filter.go
Normal file
8
pkg/exploit/ldap/core/filter/filter.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package filter
|
||||
|
||||
import "strings"
|
||||
|
||||
// LdapFilter ldap过滤器
|
||||
func LdapFilter(needle string, filterDN string) string {
|
||||
return strings.Replace(filterDN, "{username}", needle, -1)
|
||||
}
|
||||
69
pkg/exploit/ldap/core/query/flags.go
Normal file
69
pkg/exploit/ldap/core/query/flags.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package query
|
||||
|
||||
var PwdFlags = map[int]string{
|
||||
0x01: "PASSWORD_COMPLEX",
|
||||
0x02: "PASSWORD_NO_ANON_CHANGE",
|
||||
0x04: "PASSWORD_NO_CLEAR_CHANGE",
|
||||
0x08: "LOCKOUT_ADMINS",
|
||||
0x10: "PASSWORD_STORE_CLEARTEXT",
|
||||
0x20: "REFUSE_PASSWORD_CHANGE",
|
||||
}
|
||||
|
||||
var UacFlags = map[int]string{
|
||||
0x00000002: "ACCOUNT_DISABLED",
|
||||
0x00000010: "ACCOUNT_LOCKED",
|
||||
0x00000020: "PASSWD_NOTREQD",
|
||||
0x00000040: "PASSWD_CANT_CHANGE",
|
||||
0x00000080: "PASSWORD_STORE_CLEARTEXT",
|
||||
0x00000200: "NORMAL_ACCOUNT",
|
||||
0x00001000: "WORKSTATION_ACCOUNT",
|
||||
0x00002000: "SERVER_TRUST_ACCOUNT",
|
||||
0x00010000: "DONT_EXPIRE_PASSWD",
|
||||
0x00040000: "SMARTCARD_REQUIRED",
|
||||
0x00080000: "TRUSTED_FOR_DELEGATION",
|
||||
0x00100000: "NOT_DELEGATED",
|
||||
0x00200000: "USE_DES_KEY_ONLY",
|
||||
0x00400000: "DONT_REQ_PREAUTH",
|
||||
0x00800000: "PASSWORD_EXPIRED",
|
||||
0x01000000: "TRUSTED_TO_AUTH_FOR_DELEGATION",
|
||||
0x04000000: "PARTIAL_SECRETS_ACCOUNT",
|
||||
}
|
||||
|
||||
var SamType = map[int64]string{
|
||||
0x0: "SAM_DOMAIN_OBJECT",
|
||||
0x10000000: "SAM_GROUP_OBJECT",
|
||||
0x10000001: "SAM_NON_SECURITY_GROUP_OBJECT",
|
||||
0x20000000: "SAM_ALIAS_OBJECT",
|
||||
0x20000001: "SAM_NON_SECURITY_ALIAS_OBJECT",
|
||||
0x30000000: "SAM_USER_OBJECT",
|
||||
0x30000001: "SAM_MACHINE_ACCOUNT",
|
||||
0x30000002: "SAM_TRUST_ACCOUNT",
|
||||
0x40000000: "SAM_APP_BASIC_GROUP",
|
||||
0x40000001: "SAM_APP_QUERY_GROUP",
|
||||
0x7fffffff: "SAM_ACCOUNT_TYPE_MAX",
|
||||
}
|
||||
|
||||
var Trust = map[int]string{
|
||||
0x00000001: "NON_TRANSITIVE",
|
||||
0x00000002: "UPLEVEL_ONLY",
|
||||
0x00000004: "QUARANTINED_DOMAIN",
|
||||
0x00000008: "FOREST_TRANSITIVE",
|
||||
0x00000010: "CROSS_ORGANIZATION",
|
||||
0x00000020: "WITHIN_FOREST",
|
||||
0x00000040: "TREAT_AS_EXTERNAL",
|
||||
0x00000080: "USES_RC4_ENCRYPTION",
|
||||
0x00000200: "CROSS_ORGANIZATION_NO_TGT_DELEGATION",
|
||||
0x00000400: "PIM_TRUST",
|
||||
0x00000800: "CROSS_ORGANIZATION_ENABLE_TGT_DELEGATION",
|
||||
}
|
||||
var TrustDirections = map[int]string{
|
||||
0x01: "INBOUND",
|
||||
0x02: "OUTBOUND",
|
||||
0x03: "BIDIRECTIONAL",
|
||||
}
|
||||
|
||||
var TrustType = map[int]string{
|
||||
0x01: "DOWNLEVEL",
|
||||
0x02: "UPLEVEL",
|
||||
0x03: "MIT",
|
||||
}
|
||||
60
pkg/exploit/ldap/core/query/object.go
Normal file
60
pkg/exploit/ldap/core/query/object.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package query
|
||||
|
||||
// LdapQueries ldap的查询字符串
|
||||
var LdapQueries = map[string]string{
|
||||
"users": "(objectClass=user)",
|
||||
"groups": "(objectClass=group)",
|
||||
"computers": "(objectClass=Computer)",
|
||||
"dc": "(&(objectCategory=Computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))",
|
||||
"gpo": "(objectClass=groupPolicyContainer)",
|
||||
"spn": "(&(&(servicePrincipalName=*)(UserAccountControl:1.2.840.113556.1.4.803:=512))(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))",
|
||||
"unconstrained-users": "(&(&(objectCategory=person)(objectClass=user))(userAccountControl:1.2.840.113556.1.4.803:=524288))",
|
||||
"unconstrained-computers": "(&(objectCategory=computer)(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))",
|
||||
"ms-sql": "(&(objectCategory=computer)(servicePrincipalName=MSSQLSvc*))",
|
||||
"never-loggedon": "(&(objectCategory=person)(objectClass=user)(|(lastLogonTimestamp=0)(!(lastLogonTimestamp=*))))",
|
||||
"admin-priv": "(adminCount=1)",
|
||||
"domain-trust": "(objectClass=trustedDomain)",
|
||||
"ou": "(&(objectCategory=organizationalUnit)(ou=*))",
|
||||
"group-members": "(&(objectCategory=user)(memberOf={DN}))",
|
||||
"specific-users": "(&(objectCategory=user)(sAMAccountName={SAM}))",
|
||||
"specific-computers": "(&(objectClass=Computer)(cn={SAM}))",
|
||||
"specific-groups": "(&(objectCategory=group)(sAMAccountName={SAM}))",
|
||||
"specific-spn": "(&(&(servicePrincipalName=*)(cn={SAM})(UserAccountControl:1.2.840.113556.1.4.803:=512))(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))",
|
||||
"specific-ms-sql": "(&(objectCategory=computer)(cn={SAM})(servicePrincipalName=MSSQLSvc*))",
|
||||
"asreproast": "(&(objectClass=user)(objectCategory=user)(useraccountcontrol:1.2.840.113556.1.4.803:=4194304))",
|
||||
"unconstrained": "(|(&(objectClass=Computer)(useraccountcontrol:1.2.840.113556.1.4.803:=524288))(&(objectClass=user)(useraccountcontrol:1.2.840.113556.1.4.803:=524288)))",
|
||||
}
|
||||
|
||||
var ldapCommands = map[string]string{
|
||||
"users": "Users",
|
||||
"user-logs": "User Properties",
|
||||
"groups": "Groups",
|
||||
"computers": "Computers",
|
||||
"dc": "Domain Controllers",
|
||||
"gpo": "Group Policy Objects",
|
||||
"spn": "Service Principal Names",
|
||||
"never-loggedon": "Users Never LoggedOn",
|
||||
"ms-sql": "MS-SQL Servers",
|
||||
"admin-priv": "Admin Priv",
|
||||
"domain-trust": "Trusted Domain",
|
||||
"ou": "Organizational Units",
|
||||
"asreproast": "AS-REP Roastable Accounts",
|
||||
"unconstrained": "Unconstrained Delegation",
|
||||
}
|
||||
|
||||
var LdapCommandAndFilter = map[string]string{
|
||||
"users": "full-data",
|
||||
"user-logs": "",
|
||||
"groups": "full-data",
|
||||
"computers": "full-data",
|
||||
"dc": "",
|
||||
"gpo": "",
|
||||
"spn": "",
|
||||
"never-loggedon": "",
|
||||
"ms-sql": "full-data",
|
||||
"admin-priv": "",
|
||||
"domain-trust": "",
|
||||
"ou": "",
|
||||
"asreproast": "",
|
||||
"unconstrained": "",
|
||||
}
|
||||
197
pkg/exploit/ldap/core/query/query.go
Normal file
197
pkg/exploit/ldap/core/query/query.go
Normal file
@@ -0,0 +1,197 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"Yasso/core/logger"
|
||||
"github.com/jedib0t/go-pretty/v6/table"
|
||||
"gopkg.in/ldap.v2"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
LdapServer string // dc地址
|
||||
LdapUser string // 用户名(域用户即可)
|
||||
LdapPassword string // 密码
|
||||
}
|
||||
|
||||
// ldap的连接函数
|
||||
func (s *Server) ldapConn() (*ldap.Conn, bool, error) {
|
||||
conn, err := ldap.Dial("tcp", s.LdapServer)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if err := conn.Bind(s.LdapUser, s.LdapPassword); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return conn, true, nil
|
||||
}
|
||||
|
||||
func LdapListQuery(dc, user, pass, baseDN, command, filter, name string, all bool) {
|
||||
server := Server{
|
||||
LdapServer: dc,
|
||||
LdapPassword: pass,
|
||||
LdapUser: user,
|
||||
}
|
||||
conn, flag, err := server.ldapConn()
|
||||
defer conn.Close()
|
||||
if flag == false || err != nil {
|
||||
logger.Fatal("ldap server connect failed")
|
||||
return
|
||||
}
|
||||
if all == true {
|
||||
// 查询全部ldap并采用full-data过滤器
|
||||
for i, f := range LdapCommandAndFilter {
|
||||
err := LdapQuery(conn, baseDN, i, f, name)
|
||||
if err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err := LdapQuery(conn, baseDN, command, filter, name)
|
||||
if err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LdapQuery 传入baseDN,
|
||||
func LdapQuery(conn *ldap.Conn, baseDN string, command string, filter string, name string) error {
|
||||
t := table.NewWriter()
|
||||
t.SetOutputMirror(os.Stdout)
|
||||
t.AppendHeader(table.Row{ldapCommands[command]})
|
||||
t.SetColumnConfigs([]table.ColumnConfig{
|
||||
{
|
||||
Name: ldapCommands[command],
|
||||
WidthMin: 20,
|
||||
WidthMax: 100,
|
||||
},
|
||||
})
|
||||
if command == "users" && filter == "list" && name == "" {
|
||||
if err := LdapListResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "users" && filter == "full-data" && name == "" {
|
||||
if err := LdapFullResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "users" && name != "" && filter != "membership" {
|
||||
if err := LdapSpecificFullResolver(t, conn, baseDN, name, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "users" && name != "" && filter == "membership" {
|
||||
if err := LdapUserMemberShipResolver(t, conn, baseDN, name, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "computers" && filter == "list" && name == "" {
|
||||
if err := LdapListResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "computers" && filter == "full-data" && name == "" {
|
||||
if err := LdapFullResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "computers" && name != "" {
|
||||
if err := LdapSpecificFullResolver(t, conn, baseDN, name, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "groups" && filter == "list" && name == "" {
|
||||
if err := LdapListResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "groups" && filter == "full-data" && name == "" {
|
||||
if err := LdapFullResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "groups" && name != "" && filter != "membership" {
|
||||
if err := LdapSpecificFullResolver(t, conn, baseDN, name, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "groups" && filter == "membership" && name != "" {
|
||||
if err := LdapGroupResolver(t, conn, baseDN, name); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "dc" {
|
||||
if err := LdapFullResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "domain-trust" {
|
||||
if err := LdapFullResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "spn" && filter == "list" && name == "" {
|
||||
if err := LdapListResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "spn" && filter == "full-data" && name == "" {
|
||||
if err := LdapFullResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "spn" && name != "" {
|
||||
if err := LdapSpecificFullResolver(t, conn, baseDN, name, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "never-loggedon" && filter == "list" && name == "" {
|
||||
if err := LdapListResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "gpo" && name == "" {
|
||||
if err := LdapFullResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "ou" && name == "" {
|
||||
if err := LdapFullResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "ms-sql" && filter == "list" && name == "" {
|
||||
if err := LdapListResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "ms-sql" && filter == "full-data" && name == "" {
|
||||
if err := LdapFullResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "ms-sql" && name != "" {
|
||||
if err := LdapSpecificFullResolver(t, conn, baseDN, name, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "asreproast" {
|
||||
if err := LdapListResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "unconstrained" {
|
||||
if err := LdapListResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
if command == "admin-priv" {
|
||||
if err := LdapListResolver(t, conn, baseDN, command); err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
t.Render()
|
||||
return nil
|
||||
}
|
||||
433
pkg/exploit/ldap/core/query/resolver.go
Normal file
433
pkg/exploit/ldap/core/query/resolver.go
Normal file
@@ -0,0 +1,433 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"Yasso/pkg/exploit/ldap/core/filter"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"github.com/audibleblink/bamflags"
|
||||
"github.com/bwmarrin/go-objectsid"
|
||||
"github.com/jedib0t/go-pretty/v6/table"
|
||||
"gopkg.in/ldap.v2"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// LdapListResolver ldap查询解析器
|
||||
func LdapListResolver(t table.Writer, conn *ldap.Conn, baseDN string, command string) error {
|
||||
res, err := conn.SearchWithPaging(ldap.NewSearchRequest(
|
||||
baseDN,
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases,
|
||||
math.MaxInt32,
|
||||
0,
|
||||
false,
|
||||
filter.LdapFilter("*", LdapQueries[command]),
|
||||
[]string{},
|
||||
nil,
|
||||
), math.MaxInt32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 查询到数据
|
||||
if len(res.Entries) > 0 {
|
||||
for _, m := range res.Entries {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf(" - %s", m.GetAttributeValue("sAMAccountName"))},
|
||||
})
|
||||
}
|
||||
t.AppendSeparator()
|
||||
if command == "users" {
|
||||
t.AppendRows([]table.Row{
|
||||
{strconv.Itoa(len(res.Entries)) + "Domain Users Found"},
|
||||
})
|
||||
}
|
||||
if command == "computers" {
|
||||
t.AppendRows([]table.Row{
|
||||
{strconv.Itoa(len(res.Entries)) + " Domain Computers Found"},
|
||||
})
|
||||
}
|
||||
if command == "groups" {
|
||||
t.AppendRows([]table.Row{
|
||||
{strconv.Itoa(len(res.Entries)) + " Domain Groups Found"},
|
||||
})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LdapFullResolver ldap的完全解析器
|
||||
func LdapFullResolver(t table.Writer, conn *ldap.Conn, baseDN string, command string) error {
|
||||
res, err := conn.SearchWithPaging(ldap.NewSearchRequest(
|
||||
baseDN,
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases,
|
||||
math.MaxInt32,
|
||||
0,
|
||||
false,
|
||||
filter.LdapFilter("*", LdapQueries[command]),
|
||||
[]string{},
|
||||
nil,
|
||||
), math.MaxInt32)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
// 查询到数据
|
||||
if len(res.Entries) > 0 {
|
||||
for _, m := range res.Entries {
|
||||
LdapResolver(m, t)
|
||||
t.AppendSeparator()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LdapSpecificFullResolver ldap的特殊解析器
|
||||
func LdapSpecificFullResolver(t table.Writer, conn *ldap.Conn, baseDN string, name string, command string) error {
|
||||
res, err := conn.SearchWithPaging(ldap.NewSearchRequest(
|
||||
baseDN,
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases,
|
||||
math.MaxInt32,
|
||||
0,
|
||||
false,
|
||||
filter.LdapFilter("*", strings.ReplaceAll(LdapQueries[fmt.Sprintf("specific-%s", command)], "{SAM}", name)),
|
||||
[]string{},
|
||||
nil,
|
||||
), math.MaxInt32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(res.Entries) > 0 {
|
||||
for _, m := range res.Entries {
|
||||
LdapResolver(m, t)
|
||||
t.AppendSeparator()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func LdapUserMemberShipResolver(t table.Writer, conn *ldap.Conn, baseDN string, name string, command string) error {
|
||||
res, err := conn.SearchWithPaging(ldap.NewSearchRequest(
|
||||
baseDN,
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases,
|
||||
math.MaxInt32,
|
||||
0,
|
||||
false,
|
||||
filter.LdapFilter("*", strings.ReplaceAll(LdapQueries[fmt.Sprintf("specific-%s", command)], "{SAM}", name)),
|
||||
[]string{},
|
||||
nil,
|
||||
), math.MaxInt32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(res.Entries) > 0 {
|
||||
for _, m := range res.Entries {
|
||||
if len(m.GetAttributeValue("memberOf")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Member of: \n\t%s", strings.Join(m.GetAttributeValues("memberOf"), "\n\t"))},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func LdapGroupDN(conn *ldap.Conn, baseDN string, name string) string {
|
||||
res, err := conn.SearchWithPaging(ldap.NewSearchRequest(
|
||||
baseDN,
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases,
|
||||
math.MaxInt32,
|
||||
0,
|
||||
false,
|
||||
filter.LdapFilter("*", strings.ReplaceAll(LdapQueries["specific-groups"], "{SAM}", name)),
|
||||
[]string{},
|
||||
nil,
|
||||
), math.MaxInt32)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
if len(res.Entries) > 0 {
|
||||
for _, m := range res.Entries {
|
||||
return m.DN
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func LdapGroupResolver(t table.Writer, conn *ldap.Conn, baseDN string, name string) error {
|
||||
result, err := conn.SearchWithPaging(ldap.NewSearchRequest(
|
||||
baseDN,
|
||||
ldap.ScopeWholeSubtree,
|
||||
ldap.NeverDerefAliases,
|
||||
math.MaxInt32,
|
||||
0,
|
||||
false,
|
||||
filter.LdapFilter("*", strings.ReplaceAll(LdapQueries["group-members"], "{DN}", LdapGroupDN(conn, baseDN, name))),
|
||||
[]string{},
|
||||
nil,
|
||||
), math.MaxInt32)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
if len(result.Entries) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{"Domain users in group: "},
|
||||
})
|
||||
for _, m := range result.Entries {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf(" - %s", m.GetAttributeValue("sAMAccountName"))},
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func LdapParse(attr int64, Map map[int]string) []string {
|
||||
values, err := bamflags.ParseInt(attr)
|
||||
if err != nil {
|
||||
return []string{}
|
||||
}
|
||||
var all []string
|
||||
for _, value := range values {
|
||||
if propName := Map[value]; propName != "" {
|
||||
all = append(all, propName)
|
||||
}
|
||||
}
|
||||
return all
|
||||
}
|
||||
|
||||
func LdapGUID(b []byte) (string, error) {
|
||||
if len(b) != 16 {
|
||||
return "", fmt.Errorf("guid must be 16 bytes")
|
||||
}
|
||||
return fmt.Sprintf(
|
||||
"%08x-%04x-%04x-%04x-%012x",
|
||||
binary.LittleEndian.Uint32(b[:4]),
|
||||
binary.LittleEndian.Uint16(b[4:6]),
|
||||
binary.LittleEndian.Uint16(b[6:8]),
|
||||
b[8:10],
|
||||
b[10:]), nil
|
||||
}
|
||||
|
||||
func LdapSID(b []byte) (string, error) {
|
||||
if len(b) < 12 {
|
||||
return "", fmt.Errorf("[+]Invalid Windows SID")
|
||||
}
|
||||
sid := objectsid.Decode(b)
|
||||
return sid.String(), nil
|
||||
}
|
||||
|
||||
// LdapResolver ldap的解析器
|
||||
func LdapResolver(entry *ldap.Entry, t table.Writer) {
|
||||
// DN
|
||||
if len(entry.DN) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("DN: %s", entry.DN)},
|
||||
})
|
||||
}
|
||||
// 用户名
|
||||
if len(entry.GetAttributeValue("sAMAccountName")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("SAM Account Name: %s", entry.GetAttributeValue("sAMAccountName"))},
|
||||
})
|
||||
}
|
||||
// 用户名类型
|
||||
if len(entry.GetAttributeValue("sAMAccountType")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("SAM Account Type: %s", entry.GetAttributeValue("sAMAccountType"))},
|
||||
})
|
||||
}
|
||||
// Mail
|
||||
if len(entry.GetAttributeValue("mail")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Mail ID: %s", entry.GetAttributeValue("mail"))},
|
||||
})
|
||||
}
|
||||
// UID
|
||||
if len(entry.GetAttributeValue("uid")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("UID: %s", entry.GetAttributeValue("uid"))},
|
||||
})
|
||||
}
|
||||
// OU
|
||||
if len(entry.GetAttributeValue("ou")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("OU: %s", entry.GetAttributeValue("ou"))},
|
||||
})
|
||||
}
|
||||
// CN
|
||||
if len(entry.GetAttributeValue("cn")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("CN: %s", entry.GetAttributeValue("cn"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("givenName")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Given Name: %s", entry.GetAttributeValue("givenName"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("sn")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("SN: %s", entry.GetAttributeValue("sn"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("description")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Description: %s", entry.GetAttributeValue("description"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("title")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Title: %s", entry.GetAttributeValue("title"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("c")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Country: %s", entry.GetAttributeValue("c"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("co")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Country Code: %s", entry.GetAttributeValue("co"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("l")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("City: %s", entry.GetAttributeValue("l"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("st")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("State: %s", entry.GetAttributeValue("st"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("streetAddress")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Street Address: %s", entry.GetAttributeValue("streetAddress"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("postalCode")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Postal Code: %s", entry.GetAttributeValue("postalCode"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("postOfficeBox")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Post Office Box: %s", entry.GetAttributeValue("postOfficeBox"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("company")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Company: %s", entry.GetAttributeValue("company"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("instanceType")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Instance Type: %s", entry.GetAttributeValue("instanceType"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("objectClass")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Object Class: %s", strings.Join(entry.GetAttributeValues("objectClass"), ", "))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("objectCategory")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Object Category: %s", entry.GetAttributeValue("objectCategory"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("memberOf")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Member Of: \n\t%s", strings.Join(entry.GetAttributeValues("memberOf"), "\n\t"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("dNSHostName")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("DNS Host Name: %s", entry.GetAttributeValue("dNSHostName"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("servicePrincipalName")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Service Principal Name (SPN): \n\t%s", strings.Join(entry.GetAttributeValues("servicePrincipalName"), "\n\t"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("operatingSystem")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Operating System: %s", entry.GetAttributeValue("operatingSystem"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("operatingSystemVersion")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Operating System Version: %s", entry.GetAttributeValue("operatingSystemVersion"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("userAccountControl")) > 0 {
|
||||
uacFlag, err := strconv.ParseInt(entry.GetAttributeValue("userAccountControl"), 0, 64)
|
||||
if err != nil {
|
||||
//do nothing
|
||||
} else {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("UAC Flag: %s", strings.Join(LdapParse(uacFlag, UacFlags)[:], ","))},
|
||||
})
|
||||
}
|
||||
}
|
||||
if len(entry.GetAttributeValue("userAccountControl")) > 0 {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("User Account Control: %s", entry.GetAttributeValue("userAccountControl"))},
|
||||
})
|
||||
}
|
||||
if len(entry.GetAttributeValue("trustType")) > 0 {
|
||||
trustType, err := strconv.ParseInt(entry.GetAttributeValue("trustType"), 0, 64)
|
||||
if err != nil {
|
||||
//do nothing
|
||||
} else {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Trust Type: %s", strings.Join(LdapParse(trustType, TrustType)[:], ","))},
|
||||
})
|
||||
}
|
||||
}
|
||||
if len(entry.GetAttributeValue("trustDirection")) > 0 {
|
||||
trustDirection, err := strconv.ParseInt(entry.GetAttributeValue("trustDirection"), 0, 64)
|
||||
if err != nil {
|
||||
//do nothing
|
||||
} else {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Trust Direction: %s", strings.Join(LdapParse(trustDirection, TrustDirections)[:], ","))},
|
||||
})
|
||||
}
|
||||
}
|
||||
if len(entry.GetAttributeValue("trustAttributes")) > 0 {
|
||||
trustAttributes, err := strconv.ParseInt(entry.GetAttributeValue("trustAttributes"), 0, 64)
|
||||
if err != nil {
|
||||
//do nothing
|
||||
} else {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Trust Attribute: %s", strings.Join(LdapParse(trustAttributes, Trust)[:], ","))},
|
||||
})
|
||||
}
|
||||
}
|
||||
if len(entry.GetAttributeValue("objectGUID")) > 0 {
|
||||
guid, err := LdapGUID(entry.GetRawAttributeValue("objectGUID"))
|
||||
if err != nil {
|
||||
//do nothing
|
||||
} else {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Object GUID: %s", guid)},
|
||||
})
|
||||
}
|
||||
}
|
||||
if len(entry.GetAttributeValue("objectSid")) > 0 {
|
||||
sidByte := []byte(entry.GetAttributeValue("objectSid"))
|
||||
sid, err := LdapSID(sidByte)
|
||||
if err != nil {
|
||||
//do nothing
|
||||
} else {
|
||||
t.AppendRows([]table.Row{
|
||||
{fmt.Sprintf("Object SID: %s", sid)},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
44
pkg/exploit/ldap/ldap.go
Normal file
44
pkg/exploit/ldap/ldap.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"Yasso/pkg/exploit/ldap/core/query"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// LdapAuthAndQuery ldap 认证并且查询目标
|
||||
// 设置参数 command , filter, user , password, dc host , name
|
||||
func LdapAuthAndQuery(ldapServer, ldapUser, ldapPassword, command, filter, name string, all bool) {
|
||||
s := strings.Split(ldapServer, ".")
|
||||
baseDN := ""
|
||||
for x := 1; x < len(s); x++ {
|
||||
if x == len(s)-1 {
|
||||
baseDN += "DC=" + s[x]
|
||||
} else {
|
||||
baseDN += "DC=" + s[x] + ","
|
||||
}
|
||||
}
|
||||
ldapServer = fmt.Sprintf("%s:389", ldapServer)
|
||||
query.LdapListQuery(ldapServer, ldapUser, ldapPassword, baseDN, command, filter, name, all)
|
||||
}
|
||||
|
||||
func ListLdapCommand() {
|
||||
fmt.Println(" 可执行的查询命令")
|
||||
fmt.Println(" dc - 列出域控制器")
|
||||
fmt.Println(" domain-trust - 列出域信任关系")
|
||||
fmt.Println(" users - 列出域内全部用户")
|
||||
fmt.Println(" computers - 列出域内全部计算机")
|
||||
fmt.Println(" groups - 列出域内组和成员")
|
||||
fmt.Println(" spn - 列出服务的spn对象")
|
||||
fmt.Println(" never-loggedon - 列出域内从未登陆过的用户")
|
||||
fmt.Println(" gpo - 列出gpo规则对象")
|
||||
fmt.Println(" ou - 列出组织单位")
|
||||
fmt.Println(" ms-sql - 列出SQL Server服务(注册的)")
|
||||
fmt.Println(" asreproast - 列出AS-REP可托管账户")
|
||||
fmt.Println(" unconstrained - 列出不受约束委派的用户")
|
||||
fmt.Println(" admin-priv - 列出域内管理员权限组")
|
||||
fmt.Println(" 可执行的过滤器指令(users,groups,computers)")
|
||||
fmt.Println(" list - 仅仅列出全部对象")
|
||||
fmt.Println(" full-data - 列出全部对象带有对象属性")
|
||||
fmt.Println(" membership - 列出全部的成员从一个对象当中")
|
||||
}
|
||||
Reference in New Issue
Block a user