Phân tích nhanh lỗi format string SSID trên IPhone

ADMIN
12:29 23/06/2021

Vài ngày trước, một người dùng đã upload video lỗi wifi của IOS lên twitter:

https://twitter.com/vm_call/status/1405937492642123782

Nhìn sơ thì có vẻ dịch vụ Wifi bị format string, lỗi gần như "tuyệt chủng" ngày nay. 

Người dùng chichou đã phân tích về lỗi khá hiếm gặp này, và chúng mình xin phép dịch lại bài này:

 

Đầu tiên, setup một trạm phát wifi có tên như "%p%s%s%s%s%n", và kết nối vào mạng đó bằng Iphone. Dịch vụ nền wifi, wifid, ngay sau đó liền bị crash. Nội dung file  symbolicated crash log như sau:

 

Thread 2 name:  Dispatch queue: com.apple.wifid.managerQueue
Thread 2 Crashed:
0   libsystem_platform.dylib        0x00000001ebcb9724 _platform_strlen + 4
1   CoreFoundation                  0x00000001a381d84c __CFStringAppendFormatCore + 8812
2   CoreFoundation                  0x00000001a381efa8 _CFStringCreateWithFormatAndArgumentsReturningMetadata + 160
3   WiFiPolicy                      0x00000001d0895f8c -[WFLogger WFLog:message:] + 192
4   ???                             0x000000010692c00c 0 + 4405248012
5   wifid                           0x0000000100f58a74 0x100e40000 + 1149556
6   wifid                           0x0000000100f58c74 0x100e40000 + 1150068

Vây đây chắc chắn là lỗi format string rồi!

Dịch ngược hàm -[WFLogger WFLog:message:] trong ndyld_shared_cache. Hàm này có hai tham chiếu đến CFStringCreateWithFormatAndArguments.

v7 = j__CFStringCreateWithCString_107(0LL, a4, 0x8000100u); // the format string
    if ( v7 || (v7 = j__CFStringCreateWithCString_107(0LL, a4, 0)) != 0LL )
    {
      if ( self->_destination == 2 )
      {
        v8 = j__CFStringCreateWithFormatAndArguments_26(0LL, 0LL, v7, v21);
        v18[3] = (__int64)v8;
      }

và ở đây

      if ( self->_destination != 2
        && (!self->_wflRunningOnWatchClassDevice || self->_wflEnableDualLoggingOnWatchClassDevice) )
      {
        *(_QWORD *)&v16.tm_sec = 0LL;
        *(_QWORD *)&v16.tm_hour = &v16;
        *(_QWORD *)&v16.tm_mon = 0x2020000000LL;
        *(_QWORD *)&v16.tm_wday = 0LL;
        v10 = j__CFStringCreateWithFormatAndArguments_26(0LL, 0LL, v7, v21); // <-- here

 

Bởi vì hàm này được gọi nhiều lần quá, việc debug với lldb sẽ là công việc đầy chông gai. Thay vào đó, mình sẽ attach frida vào :  frida-trace -U wifid -m '-[WFLogger WFLog:message:]'  và sửa script một xíu:

 

  onEnter(log, args, state) {
    const msg = '' + args[3].readUtf8String();
    log(-[WFLogger WFLog:</span><span class="p">${</span><span class="nx">args</span><span class="p">[</span><span class="mi">2</span><span class="p">]}</span><span class="s2"> message:</span><span class="p">${</span><span class="nx">msg</span><span class="p">}</span><span class="s2">]);
    if (msg.indexOf('%p%s%s%s%s%n') > -1) {
      for (let i = 3; i < 10; i++) {
        log(args[i], JSON.stringify(Process.findRangeByAddress(args[i])));
      }
      log('called from:\n' +
        Thread.backtrace(this.context, Backtracer.ACCURATE)
        .map(DebugSymbol.fromAddress).join('\n') + '\n');
    }
  },

Đoạn log ngay trước khi crash như sau:

17863 ms -[WFLogger WFLog:0x3 message:Dequeuing command type: “%@” pending commands: %ld]

17863 ms -[WFLogger WFLog:0x3 message:{ASSOC+} Attempting Apple80211AssociateAsync to %p%s%s%s%s%n]

 

v27 = sub_1000A25D4(v21);
v28 = objc_msgSend(
        &OBJC_CLASS___NSString,
        "stringWithFormat:",
        CFSTR("Attempting Apple80211AssociateAsync to %@"),
        v27);
v29 = objc_msgSend(&OBJC_CLASS___NSString, "stringWithFormat:", CFSTR("{ %@+} %@"), CFSTR("ASSOC"), v28);
v30 = objc_autoreleasePoolPush();
v31 = (void *)qword_100251888;
if ( qword_100251888 )
{
    v32 = objc_msgSend(v29, "UTF8String");
    objc_msgSend(v31, "WFLog:message:", 3LL, v32);
}
objc_autoreleasePoolPop(v30);

 

nó nối SSID thành format string và chuyển qua phương thức WFLog:message: . Vì tham số bên cạnh là 3, ta có thể suy ra được là tham chiếu thứ hai của hàm  CFStringCreateWithFormatAndArguments  đã gây ra lỗi

Các tham số còn lại có vẻ không thay đổi được, nên lỗi này không có khả nang bị thai khác sâu hơn. Suy cho cùng, muốn thai khác lỗi này, nạn nhân phải kết nối đến mạng wifi này, mà nhìn tên ssid đã thấy đáng ngờ. Còn nhiều cách khác hiệu quả hơn phương pháp này.

Nguồn: Chichou.me 

TIN LIÊN QUAN
CLB An toàn Thông tin WannaW^n chia sẻ một số Challenges giải được và việc chia sẻ writeup nhằm mục đích giao lưu học thuật. Mọi đóng-góp ý-kiến bọn mình luôn-luôn tiếp nhận qua mail: wannaone.uit@gmail.com hoặc inseclab@uit.edu.vn và fanpage: fb.com/inseclab Tuần vừa qua thì mình có tham gia giải...
  Phòng thực hành Mạng - B2.04 thuộc quản lý của Phòng thí nghiệm An toàn thông tin, nhằm cung cấp môi trường thực hành Mạng cho việc giảng dạy và học tập các môn học. Để xem được liên kết và đăng ký, vui lòng đăng nhập bằng tài...