worawit / MS17-010

MS17-010
2.13k stars 1.1k forks source link

Fix offsets on XP SP0 and SP1 #24

Closed ghost closed 6 years ago

ghost commented 6 years ago

Adds an extra check to fall back to different offsets if secCtxGroupCount appears too large on XP SP0 and SP1.

I have found the correct values at offset 0x40 and 0x5c, it looks like 3 extra pointers were added to token data between the releases. They are not the same as Win2k offsets.

Fun fact: this is probably because SP2 introduces security center and a bunch of other "modern" features.

'TOKEN_USER_GROUP_CNT_OFFSET': 0x40,  #0x4c,
'TOKEN_USER_GROUP_ADDR_OFFSET': 0x5c  #0x68,

SP0 token data:

4e744c6d53737020000000000000000091200200000000008c200200000000000000000000000000ffffffffffffff7f28e89aff9020020000000000000000000300000000000000000000004c000000f40100000000000000000000b02f57e100000000b89f16e1b02f57e1b89f16e1000000000200000002000000000033000000000000000000c82f57e107000000d42f57e100000000e02f57e10700000001010000000000050700000001010000000000000000000001010000000000050200000000000000040000000400000000000000000000000004310c476c613533050506000000000000008000000000000000003305050600000000089048e1

SP2 token data:

4e744c6d537370200000000000000000fd61050000000000f8610500000000000000000000000000ffffffffffffff7ff8feb7ff390035000000000010000000ff61050000000000000000000300000000000000000000004c000000f4010000000000000000000070b946e100000000b83384e170b946e1b83384e100000000020000000200000000000000000045000000000000000000000000000000000088b946e10700000094b946e100000000a0b946e1070000000101000000000005070000000101000000000000000000000101000000000005020000004400310035003600450034007d0000007d0000002404060c434d566100002400766b0d00

ghost commented 6 years ago

@worawit it unpacks from 32-bit integer... is checking >4 groups going to be enough? (I think it will be fine at least for unauthed)

Can you think of another way to detect wrong offset given that TOKEN data?

Common values I've seen are

2000 SP 4 = 4 XP SP 0-3 = 3 2003 SP 2 = 5

worawit commented 6 years ago

The token struct for XP SP2 should be same as https://github.com/lmr3796/WRK-1.2/blob/master/base/ntos/se/tokenp.h#L235

RestrictedSidCount always be 0 for SMB session. PrivilegeCount is 0 for null session. So your patch is good enough for null session.

If you want to detect wrong offset for all target, you can unpack RestrictedSidCount and RestrictedSids too which are next to UserAndGroupCount and UserAndGroups. If the offset is correct, RestrictedSidCount and RestrictedSids MUST be 0

ghost commented 6 years ago

Thanks @worawit I will look into making it a better fix with your suggestions.

ghost commented 6 years ago

I changed it to check that both RestrictedSids and RestrictedSidCount equal 0 instead of going off the group count.

Tested, works on:

worawit commented 6 years ago

Patch looks fine to me. But in validate_token_offset function I prefer

userAndGroupCount, RestrictedSidCount = unpack_from('<II', tokenData, userAndGroupCountOffset) userAndGroupsAddr, RestrictedSids = unpack_from('<'+info['PTR_FMT']*2, tokenData, userAndGroupsAddrOffset)

I think we should add userAndGroupCount == 0 or userAndGroupsAddr == 0 for checking bad offset

ghost commented 6 years ago

Good ideas, included in last commit. I also added some notes about the token struct for anyone else studying exploit in future.

re-tested against all versions