Rixstep
 About | ACP | Buy | Industry Watch | Learning Curve | News | Products | Search | Substack
Home » Industry Watch

Into the Great Wide Open

iPhone hackers are making some noise because they're learning to fly. It's almost too good to be true.



Get It

Try It

London (IDG) -- Third party applications can now be installed on the iPhone. There are now at least three ways to bypass essential security measures in the device.

Installer.app

Installer.app is a UIKit based package manager for the iPhone. It works by downloading packages over WiFi or EDGE. It supports installing, updating, and uninstalling applications.

Also available is a single command installer for Installer.app which automates the entire jailbreak and Installer.app installation process.

The Installer.app page also includes documentation for creating application packages for the iPhone.

iPHUC

The iPhone Utility Client (iPHUC) is the followup to the earlier iPhoneInterface which allows command line access to the iPhone from an external computer. It is maintained on Google Code.

Turbo SIM

The Turbo SIM hack - a combination of a blank Turbo SIM card together with AppleSaft from Bladox - makes it possible to enable all but EDGE support without the customary (expensive) AT&T activation - and it also makes it possible to use the Apple device on any GSM network with full incoming and outgoing telephony services. Further instructions can be found here.

/*
 * iPhone baseband SIM lock 0wnage PoC
 *
 * History:
 * 0.92 - User Interface, ICCID/IMSI are read from a card and
      then used with another
 * 0.91 - some fixes, PROC_8_CONFIG_INIT_BOOSTER for speedy init of ICCID file,
 *      needs bladox turbo kernel >=1.2.7
 * 0.9 - original version
 *
 * Compile, load on your leet Bladox gear
 * disable your subscription PIN and enjoy :p
 *
 * Special thanks to the baseband development team
 * It wouldn't have been so easy without you :)
 *
 * (c) 2007, collective iPhone development effort
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#include <config.h>
#include <turbo/turbo.h>

#include <stdlib.h>
#include <string.h>

#define VERSION_A    0
#define VERSION_B    92

/* *INDENT-OFF* */

static lc_char PROGMEM lc_Show[]={
        LC_EN("Show")
        LC_END
};

static lc_char PROGMEM lc_Set[]={
        LC_EN("Set")
        LC_END
};

static lc_char PROGMEM lc_WasSet[]={
        LC_EN("Following was set: ")
        LC_END
};


static lc_char PROGMEM lc_Version[]={
        LC_EN("Version")
        LC_END
};

static lc_char PROGMEM lc_AppleSaft[]={
        LC_EN("Apple Saft")
        LC_END
};

static lc_char PROGMEM lc_IMSI[]={
        LC_EN("IMSI: ")
        LC_END
};

static lc_char PROGMEM lc_ICCID[]={
        LC_EN("ICCID: ")
        LC_END
};

/* *INDENT-ON* */

#define EF_IMSI 0x6F07
#define EF_ICCID 0x2FE2

u8 PROGMEM ef_imsi_path[] = { 0x3F, 0x00, 0x7F, 0x20, 0x6F, 0x07 };
u8 PROGMEM ef_iccid_path[] = { 0x3F, 0x00, 0x2F, 0xE2 };

#define IMSI_SIZE 9
#define IMSI_RESPONSE_SIZE 15

u8 counter;
u8 *imsi;
u8 *imsi_response;
u8 file[2];

u8 *tmp_imsi;
u8 *tmp_iccid;

typedef struct _Pers_mem
{
  u8 on;
  u8 imsi[0x09];
  u8 iccid[0x0a];
}
Pers_mem;

Pers_mem *pers_mem = NULL;

void handle_sim_file (File_apdu_data * fa)
{
  u8 i;

  if (fa->ef == EF_ICCID && fa->ins == ME_CMD_READ_BINARY)
  {
    if (rb (&pers_mem->on))
    {
      dbsp ("FAKE_ICCID\n");
      //memcpy (fa->data, _att_iccid, sizeof (_att_iccid));
      memcpy (fa->data, &pers_mem->iccid[0], 0x0a);
    }
    else
    {
      dbsp ("REAL_ICCID\n");
      sim (fa->ins, fa->p1, fa->p2, fa->p3, fa->data);
    }

    fa->data[fa->p3] = 0x90;
    fa->data[fa->p3 + 1] = 0x00;
  }
  else if (fa->ef == EF_IMSI && fa->ins == ME_CMD_READ_BINARY)
  {
    sim (fa->ins, fa->p1, fa->p2, fa->p3, fa->data);
    switch (counter)
    {
      case 0:
    dbsp ("REAL_IMSI_0\n");
    /* learn and retransmit */
//        low_level_imsi_select ();
//        sim (0xB0, 0x00, 0x00, 0x09, imsi);   /* READ BINARY */
//        memcpy (fa->data, imsi, IMSI_SIZE);
    fa->data[fa->p3] = 0x90;
    fa->data[fa->p3 + 1] = 0x00;
    counter++;
    break;
      case 1:
    /* spoof */
    if (rb (&pers_mem->on))
    {
      dbsp ("FAKE_IMSI_1\n");
//        memcpy (fa->data, _att_imsi, sizeof (_att_imsi));
      memcpy (fa->data, &pers_mem->imsi[0], 0x09);
    }
    else
    {
      dbsp ("REAL_IMSI_1\n");
    }
    fa->data[fa->p3] = 0x90;
    fa->data[fa->p3 + 1] = 0x00;
    counter++;
    break;
      case 2:
    counter++;
    /* no break intended here */
      default:
    dbsp ("REAL_IMSI_2+\n");
    /* play nice */
//        memcpy (fa->data, imsi, IMSI_SIZE);
    sim (fa->ins, fa->p1, fa->p2, fa->p3, fa->data);
    fa->data[fa->p3] = 0x90;
    fa->data[fa->p3 + 1] = 0x00;
    }
  }
  else
    sim (fa->ins, fa->p1, fa->p2, fa->p3, fa->data);
}

void get_files ()
{
  u8 path[6];

  memcpy (path, ef_imsi_path, 6);
  select (path, 3);
  sim (ME_CMD_READ_BINARY, 0x00, 0x00, 0x09, tmp_imsi);
  select (0, 0);

  memcpy (path, ef_iccid_path, 4);
  select (path, 2);
  sim (ME_CMD_READ_BINARY, 0x00, 0x00, 0x0a, tmp_iccid);
  select (0, 0);
}

u8 saft_set (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *buf = buf_B ();
    u8 *r = buf;
    u8 i;

    get_files ();

    memcpy (&pers_mem->imsi[0], tmp_imsi, 9);
    memcpy (&pers_mem->iccid[0], tmp_iccid, 0x0a);
    wb (&pers_mem->on, 1);

    r = sprints (r, locale (lc_WasSet));
    r = sprintc (r, '\n');

    r = sprints (r, locale (lc_IMSI));
    for (i = 0; i < 0x09; i++)
    {
      r = sprintch (r, rb (&pers_mem->imsi[i]));
      r = sprintc (r, ' ');
    }

    r = sprints (r, locale (lc_ICCID));
    for (i = 0; i < 0x0a; i++)
    {
      r = sprintch (r, rb (&pers_mem->iccid[i]));
      r = sprintc (r, ' ');
    }
    r = sprintc (r, '\n');

    r = sprintc (r, '\0');
    i = display_text (buf, NULL);
    if (i != APP_END)
      return APP_BACK;
    return i;

    return APP_BACK;
  }
  return APP_OK;
}

u8 saft_show (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *buf = buf_B ();
    u8 *r = buf;
    u8 i;

    get_files ();

    r = sprints (r, locale (lc_IMSI));
    for (i = 0; i < 0x09; i++)
    {
      r = sprintch (r, tmp_imsi[i]);
      r = sprintc (r, ' ');
    }

    r = sprints (r, locale (lc_ICCID));
    for (i = 0; i < 0x0a; i++)
    {
      r = sprintch (r, tmp_iccid[i]);
      r = sprintc (r, ' ');
    }
    r = sprintc (r, '\n');

    r = sprintc (r, '\0');
    i = display_text (buf, NULL);
    if (i != APP_END)
      return APP_BACK;
    return i;
  }
  return APP_OK;
}

u8 saft_version (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *buf = buf_B ();
    u8 *r = buf;
    u8 i;

    r = sprints (r, locale (lc_AppleSaft));
    r = sprintc (r, ' ');

    r = sprinti (r, VERSION_A);
    r = sprintc (r, '.');
    r = sprinti (r, VERSION_B);
    r = sprintc (r, '\n');

    r = sprintc (r, '\0');
    i = display_text (buf, NULL);
    if (i != APP_END)
      return APP_BACK;
    return i;
  }
  return APP_OK;
}

SNodeP saft_n = { lc_AppleSaft, NULL };
SNodeP saft_set_n = { lc_Set, saft_set };
SNodeP saft_show_n = { lc_Show, saft_show };
SNodeP saft_version_n = { lc_Version, saft_version };

/* *INDENT-OFF* */

SEdgeP saft_edges_p[] = {
  {&saft_n, &saft_show_n},
  {&saft_n, &saft_set_n},
  {&saft_n, &saft_version_n},
  NULL
};

/* *INDENT-ON* */

void action_menu (Menu_selection_data * x)
{
  SCtx *c;

  c = spider_init ();
  c->eP = &saft_edges_p;
  c->n = &saft_n;
  spider (c);
}

void turbo_handler (u8 action, void *data)
{
  switch (action)
  {
    case ACTION_APP_REGISTER:
      {
    Pers_mem *p = emalloc (sizeof (Pers_mem));

    pers_mem = p;
    wb (&p->on, 0);
    reg_app_data (p);

    set_proc_8 (PROC_8_CONFIG_INIT_BOOSTER, 1);
      }
      break;
    case ACTION_APP_UNREGISTER:
      {
    Pers_mem *p = app_data ();

    efree (p);
      }
      break;
    case ACTION_APP_INIT:
      dbsp ("APP_INIT\n");
      counter = 0;
      pers_mem = app_data ();

      tmp_imsi = malloc (0x09);
      tmp_iccid = malloc (0x0a);

      imsi = malloc (IMSI_SIZE);
      imsi_response = malloc (IMSI_RESPONSE_SIZE);
      reg_file (ef_imsi_path, 3);
      reg_file (ef_iccid_path, 2);
      break;
    case ACTION_FILE_APDU:
      handle_sim_file (data);
      break;
    case ACTION_INSERT_MENU:
      insert_menu (locale (lc_AppleSaft));
      break;
    case ACTION_MENU_SELECTION:
      stk_thread (action_menu, NULL);
      break;
    default:
      break;
  }
}

iPhone International?

Whilst the rumour mills are suggesting Apple will release patches to close these holes they're also suggesting Apple may be readying the release of a second explicitly 'international' device that won't require safeguards such as heretofore implemented.

See Also
Wooden Leg
Hacking the iPhone
'How I Hacked the iPhone'
iPhone
Alpine Dottie
Effective UID: 0
iPhone and Security
iPhone and the Media
iPhone Hack to be Patched
iPhone OS X System Architecture


Thanks to Devon at Pixel Groovy for the excellent artwork.

About | ACP | Buy | Industry Watch | Learning Curve | News | Products | Search | Substack
Copyright © Rixstep. All rights reserved.