หลังจากที่แอปเปิลนั้นได้ออกอัพเดต iOS 7.0.6 และ iOS 6.1.6 เพื่อแก้ไขข้อผิดพลาดเกี่ยวกับความปลอดภัยในการเชื่อมต่อแบบ SSL ( ข่าวเก่า ) ทำให้มีผู้พัฒนาหลายๆ คนได้ไปตรวจสอบโค้ดในส่วนนี้สำหรับ OS X Mavericks (10.9.x) และพบว่าข้อบกพร่องนี้ก็ปรากฏอยู่ใน Mavericks ด้วยเช่นเดียวกัน
ทำให้มีผู้พัฒนาชาวเยอรมันคนหนึ่งได้ทำการแพชต์ Mavericks ตัวนี้เพื่อแก้ไขข้อบกพร่องที่เกิดขึ้น โดยแพชต์ตัวนี้รองรับเฉพาะ Mavericks แบบ 64 บิตเท่านั้น หากนำไปใช้กับเครื่อง 32 บิต จะต้องทำการพอร์ตก่อน
สิ่งที่ผู้พัฒนาค้นพบก็คือโค้ดในไฟล์ sslKeyExchange.c นั่นเอง เพราะว่ามีคำสั่ง goto fail; ถึง 2 ครั้ง
static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
uint8_t *signature, UInt16 signatureLen)
{
...if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail; <---- *** DANGER ***
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;err = sslRawVerify(ctx,
ctx->peerPubKey,
dataToSign, /* plaintext */
dataToSignLen, /* plaintext length */
signature,
signatureLen);
...
fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;}
ดังนั้นผู้พัฒนาคนนี้จึงได้รีบคิดที่จะแก้ไขปัญหานี้ เนื่องจากเป็นปัญหาที่ใหญ่พอสมควรเลยทีเดียวสำหรับ SSL ใหญ่จนบางเว็บไซต์บอกให้ไปใช้งานระบบปฏิบัติการอื่นก่อน จนนกว่าแอปเปิลจะออกแพชต์แก้ไขในเรื่องนี้ ( ข่าวเก่า )
มาดูรายละเอียดของแพชต์กันครับ
นี่คือโค้ดที่ไม่ได้ทำการแก้ไขเลยใน Security.framework binary ครับ
.text
#
# This is the original code inside the Security.framework binary
#
#__text:0000000000086C3B lea r15, _SSLHashSHA1
#__text:0000000000086C42 lea rsi, [rbp+var_C8]
#__text:0000000000086C49 mov rdi, r15
#__text:0000000000086C4C call _ReadyHash
#__text:0000000000086C51 mov ebx, eax
#__text:0000000000086C53 test ebx, ebx
#__text:0000000000086C55 jnz short loc_86C9C
#__text:0000000000086C57 mov r14, [r15+18h]
#__text:0000000000086C5B lea rdi, [rbp+var_C8]
#__text:0000000000086C62 lea rsi, [rbp+var_D8]
#__text:0000000000086C69 call r14
#__text:0000000000086C6C mov ebx, eax
#__text:0000000000086C6E test ebx, ebx
#__text:0000000000086C70 jnz short loc_86C9C
#__text:0000000000086C72 lea rdi, [rbp+var_C8]
#__text:0000000000086C79 lea rsi, [rbp+var_E8]
#__text:0000000000086C80 call r14
#__text:0000000000086C83 mov ebx, eax
#__text:0000000000086C85 test ebx, ebx
#__text:0000000000086C87 jnz short loc_86C9C
#__text:0000000000086C89 lea rdi, [rbp+var_C8]
#__text:0000000000086C90 lea rsi, [rbp+var_A8]
#__text:0000000000086C97 call r14
#__text:0000000000086C9A mov ebx, eax
โดยตัวแพชต์จะเพิ่มโค้ดลงไปที่ 0x86c90 ดังนี้ครับ
# we insert the hook at 0x86c90
lea -0xa8(%rbp), %rsi # signedParams
call *%r14 # SSLHashSHA1.update
mov %eax, %ebx
test %ebx, %ebx
jnz 1f
lea -0xc8(%rbp), %rdi # hashCtx
lea -0xb8(%rbp), %rsi # hashOut
call *0x20(%r15) # SSLHashSHA1.final
mov %eax, %ebx
test %ebx, %ebx
jnz 1fmov -0x1e0(%rbp), %r8 # signature
xor %rsi, %rsi
inc %rsi
inc %rsi
mov %r8, %rdi
sub %rsi, %rdi
call _SSLDecodeInt
cwde
cdqe
mov %rax, %r9 # signatureLen
mov %r12, %rdi # ctx
mov +0x78(%rdi), %rsi # ctx->peerPubKey
mov -0xb0(%rbp), %rdx # dataToSign from hashOut.data
mov $20, %rcx # SSL_SHA1_DIGEST_LEN
cmpb $0, -0x1a8(%rbp) # isRsa
jz 2f
sub $16, %rdx # Need MD5 so pos-SSL_MD5_DIGEST_LEN
mov $36, %rcx # dataToSignLen = SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN
2:
call _sslRawVerify
jmp label_86C9A1:jmp label_86C9C
สำหรับตัวแพชต์นั้นสามารถดาวน์โหลดได้ ที่นี่ ครับ
คำเตือน: แพชต์นี้สำหรับผู้ที่จะยอมรับความเสี่ยงในอนาคตด้วยตัวของท่านเอง ทางผู้พัฒนาจะไม่ให้การช่วยเหลือใดๆ ทั้งสิ้น
ที่มา: SektionEins โพสต์ครั้งแรกที่ ThaiApple
ภาพการใช้งานบน OS X Mavericks 10.9.1 ที่ทำงานบน VMWare
Comments
เลยที่เดียว => เลยทีเดียว
จนนกว่า => จนกว่า
แก้แล้วครับ
ต้องแก้ด้วยมั้ยครับ?
ในข่าวนี้ http://www.blognone.com/node/53648 ผมก็เขียนเรื่องแพตช์ตัวนี้ไว้แล้วนะครับ :3