cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1945
Views
0
Helpful
4
Replies

DAP LUA match ipad device unique id to cert

nick.davey
Level 1
Level 1

Hi,

I am trying to configure a DAP policy using LUA to perform a check that a cert has not been moved. I cert has been configured to store the ipads device unique id in the subject cn field, which i have verified on the device. I have configured the following LUA statement but i am not getting a match:

EVAL(endpoint.anyconnect.deviceuniqueid, "NE", endpoint.certificate.user[“0”].subject_cn, "caseless")

Is this check posssible with ipads?

Thank you.

4 Replies 4

nzaldiva
Cisco Employee
Cisco Employee

endpoint.certificate.user is passed back using hostscan.  So this feature would only be available on devices that support hostscan, like MAC, Windows and Linux

If you put the UDID in the certificate (using %MACHINEID% using SCEP/SCEP Proxy in the anyconnect profile) and the pre-registered the device by putting the UDID in the users AD record (blank field, like extensionAtribute1) you could make a comparison.

Like

EVAL(endpoint.anyconnect.deviceuniqueid, "NE", aaa["ldap"]["extensionAttribute1"],"caseless")

Today This would be supported on just about any Android version and Apple iOS up to 6.  UDID is not available in apps on iOS7

If you have access to CiscoLive materials, check out BRKSEC-2053, I cover both Desktop and Mobile cert checks.

I saw the presentation and I am having problems making this work..I am using Mac, windows and linux so the endpoint.certificate.user is actually captured by hostscan and I see it in the debug dap trace. However, my problem is with policy matching, endpoint.certificate.user[“0”].subject_cn assumes there's just 1 certificate installed on the host. I have seen devices with 64 machine certificates installed. How should I go about the lua expression so it selects the one issued by my CA or evaluates each and everyone of the 64 certs. That "0" needs to be a wildcard to whatever hostscan finds. I tried using this expression based on this link http://www.cisco.com/c/en/us/support/docs/security/asa-5500-x-series-next-generation-firewalls/115947-dap-adv-functions-00.html

assert(function()
    local match_pattern = endpoint.device.id
    local match_value   = endpoint.certificate.user["*"].subject_e
    if (type(match_value) == "string") then
        if (string.find(match_value, match_pattern) ~= nil) then
            return true
        end
    elseif (type(match_value) == "table") then
        local k,v
        for k,v in pairs(match_value) do
            if (string.find(v, match_pattern) ~= nil) then
                return true
            end
        end
     end
     return false
end ) ()

 

it never matches.. any ideas?

 

 

So in the end I had the same problem with this script.  Never really fixed it but did workaround with that script by making local match_valueX for X number of certs you think folks will have in the their store.  So most people won't have 64....but really you could cut and paste to any number you like.

assert(function()

local match_pattern = endpoint.device.hostname..".domain.com"

local match_value0 = endpoint.certificate.user["0"].subject_cn

local match_value1 = endpoint.certificate.user["1"].subject_cn

local match_value2 = endpoint.certificate.user["2"].subject_cn

if match_pattern==match_value0 then

return true

elseif match_pattern==match_value1 then

return true

elseif match_pattern==match_value2 then

return true

else

return false

end

end ) ()

 

Another option is to do a username to mapping from certificate script that simply

returns cert.subject.cn "/" cert.subject.ou (where the UDID was populated)

 

And the use a DAP to parse to verify anyconnect deviceuniqueid and aaa.cisco.username match (ie the UDID from anyconnect and what is in the cert)

 

assert function ()

local match_pattern = endpoint.anyconnect.deviceuniqueid

local match_value = aaa.cisco.username

if (type(match_value) == "string") then

if (string.find(match_value, match_pattern) ~= nil) then

return false

end

elseif (type(match_value) == "table") then

local k,v

for k,v in pairs(match_value) do

if (string.find(v, match_pattern) ~= nil) then

return false

end

end

end

return true

end) ()

the first option does work, tried doing that checking for 3 certs but then saw a few users with way more. Don't know how it would affect posture assessment times to do 20, 30 or 50 cert checks. I don't want this to be very noticeable for users. I'll try that and see how it goes.

 

Thanks!