mush.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. #!/bin/bash
  2. get_largest_nvme_namespace() {
  3. # this function doesn't exist if the version is old enough, so we redefine it
  4. local largest size tmp_size dev
  5. size=0
  6. dev=$(basename "$1")
  7. for nvme in /sys/block/"${dev%n*}"*; do
  8. tmp_size=$(cat "${nvme}"/size)
  9. if [ "${tmp_size}" -gt "${size}" ]; then
  10. largest="${nvme##*/}"
  11. size="${tmp_size}"
  12. fi
  13. done
  14. echo "${largest}"
  15. }
  16. traps() {
  17. set +e
  18. trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG
  19. trap 'echo "\"${last_command}\" command failed with exit code $?. THIS IS A BUG, REPORT IT HERE https://github.com/MercuryWorkshop/fakemurk"' EXIT
  20. trap '' INT
  21. }
  22. mush_info() {
  23. cat <<-EOF
  24. Welcome to mush, the fakemurk developer shell.
  25. If you got here by mistake, don't panic! Just close this tab and carry on.
  26. This shell contains a list of utilities for performing certain actions on a fakemurked chromebook
  27. EOF
  28. if ! test -f /mnt/stateful_partition/telemetry_selected; then
  29. read -r -p "Would you like to opt-in to telemetry? To figure out what Mercury should focus on next and get a general idea of what the most common policies are, your policy will be sent to our servers. Depending on how management is setup, this may contain the name of your school district and or wifi password. Policies that may contain that information will never be shared publicly. Would you like to enable this feature (pls say yes 🥺) [Y\n]" choice
  30. case "$choice" in
  31. n | N) : ;;
  32. *) doas touch /mnt/stateful_partition/telemetry_opted_in ;;
  33. esac
  34. doas touch /mnt/stateful_partition/telemetry_selected
  35. fi
  36. }
  37. doas() {
  38. ssh -t -p 1337 -i /rootkey -oStrictHostKeyChecking=no root@127.0.0.1 "$@"
  39. }
  40. runjob() {
  41. trap 'kill -2 $! >/dev/null 2>&1' INT
  42. (
  43. $@
  44. )
  45. trap '' INT
  46. }
  47. swallow_stdin() {
  48. while read -t 0 notused; do
  49. read input
  50. done
  51. }
  52. edit() {
  53. if which nano 2>/dev/null; then
  54. doas nano "$@"
  55. else
  56. doas vi "$@"
  57. fi
  58. }
  59. main() {
  60. traps
  61. mush_info
  62. while true; do
  63. cat <<-EOF
  64. (1) Root Shell
  65. (2) Chronos Shell
  66. (3) Crosh
  67. (4) Powerwash
  68. (5) Soft Disable Extensions
  69. (6) Hard Disable Extensions
  70. (7) Hard Enable Extensions
  71. (8) Emergency Revert & Re-Enroll
  72. (9) Edit Pollen
  73. EOF
  74. if ! test -f /mnt/stateful_partition/crouton; then
  75. echo "(10) Install Crouton"
  76. else
  77. echo "(11) Start Crouton"
  78. fi
  79. echo "(12) Attempt to update to the latest chrome os version (BETA, BUGGY, MAY BREAK)"
  80. swallow_stdin
  81. read -r -p "> (1-12): " choice
  82. case "$choice" in
  83. 1) runjob doas bash ;;
  84. 2) runjob bash ;;
  85. 3) runjob /usr/bin/crosh.old ;;
  86. 4) runjob powerwash ;;
  87. 5) runjob softdisableext ;;
  88. 6) runjob harddisableext ;;
  89. 7) runjob hardenableext ;;
  90. 8) runjob revert ;;
  91. 9) runjob edit /etc/opt/chrome/policies/managed/policy.json ;;
  92. 10) runjob install_crouton ;;
  93. 11) runjob start_crouton ;;
  94. 12) runjob attempt_update ;;
  95. *) echo "invalid option" ;;
  96. esac
  97. done
  98. }
  99. # https://chromium.googlesource.com/chromiumos/docs/+/master/lsb-release.md
  100. lsbval() {
  101. local key="$1"
  102. local lsbfile="${2:-/etc/lsb-release}"
  103. if ! echo "${key}" | grep -Eq '^[a-zA-Z0-9_]+$'; then
  104. return 1
  105. fi
  106. sed -E -n -e \
  107. "/^[[:space:]]*${key}[[:space:]]*=/{
  108. s:^[^=]+=[[:space:]]*::
  109. s:[[:space:]]+$::
  110. p
  111. }" "${lsbfile}"
  112. }
  113. get_booted_kernnum() {
  114. if doas "((\$(cgpt show -n \"$dst\" -i 2 -P) > \$(cgpt show -n \"$dst\" -i 4 -P)))"; then
  115. echo -n 2
  116. else
  117. echo -n 4
  118. fi
  119. }
  120. opposite_num() {
  121. if [ "$1" == "2" ]; then
  122. echo -n 4
  123. elif [ "$1" == "4" ]; then
  124. echo -n 2
  125. elif [ "$1" == "3" ]; then
  126. echo -n 5
  127. elif [ "$1" == "5" ]; then
  128. echo -n 3
  129. else
  130. return 1
  131. fi
  132. }
  133. attempt_update(){
  134. local builds=$(curl https://chromiumdash.appspot.com/cros/fetch_serving_builds?deviceCategory=Chrome%20OS)
  135. local board=octopus
  136. local hwid=$(jq "(.builds.$board[] | keys)[0]" <<<"$builds")
  137. local hwid=${hwid:1:-1}
  138. local latest_milestone=$(jq "(.builds.$board[].$hwid.pushRecoveries | keys) | .[length - 1]" <<<"$builds")
  139. local remote_version=$(jq ".builds.$board[].$hwid[$latest_milestone].version" <<<"$builds")
  140. local remote_version=${remote_version:1:-1}
  141. local local_version=$(lsbval GOOGLE_RELEASE)
  142. if (( ${remote_version%%\.*} > ${local_version%%\.*} )); then
  143. echo "updating to ${remote_version}. THIS WILL DELETE YOUR REVERT BACKUP AND YOU WILL NO LONGER BE ABLE TO REVERT! THIS MAY ALSO DELETE ALL USER DATA!! press enter to confirm, ctrl-c to cancel"
  144. read -r
  145. sleep 4
  146. # read choice
  147. local reco_dl=$(jq ".builds.$board[].$hwid.pushRecoveries[$latest_milestone]" <<< "$builds")
  148. local tmpdir=/mnt/stateful_partition/update_tmp/
  149. doas mkdir $tmpdir
  150. echo "downloading ${remote_version} from ${reco_dl}"
  151. curl "${reco_dl:1:-1}" | doas "dd of=$tmpdir/image.zip status=progress"
  152. echo "unzipping update binary"
  153. cat $tmpdir/image.zip | gunzip | doas "dd of=$tmpdir/image.bin status=progress"
  154. doas rm -f $tmpdir/image.zip
  155. echo "invoking image patcher"
  156. doas image_patcher.sh "$tmpdir/image.bin"
  157. local loop=$(doas losetup -f | tr -d '\r')
  158. doas losetup -P "$loop" "$tmpdir/image.bin"
  159. echo "performing update"
  160. local dst=/dev/$(get_largest_nvme_namespace)
  161. local tgt_kern=$(opposite_num $(get_booted_kernnum))
  162. local tgt_root=$(( $tgt_kern + 1 ))
  163. local kerndev=${dst}p${tgt_kern}
  164. local rootdev=${dst}p${tgt_root}
  165. echo "installing kernel patch to ${kerndev}"
  166. doas dd if="${loop}p4" of="$kerndev" status=progress
  167. echo "installing root patch to ${rootdev}"
  168. doas dd if="${loop}p3" of="$rootdev" status=progress
  169. echo "setting kernel priority"
  170. doas cgpt add "$dst" -i 4 -P 0
  171. doas cgpt add "$dst" -i 2 -P 0
  172. doas cgpt add "$dst" -i "$tgt_kern" -P 1
  173. doas crossystem.old block_devmode=0
  174. doas vpd -i RW_VPD -s block_devmode=0
  175. # doas rm -rf $tmpdir
  176. else
  177. echo "update not required"
  178. fi
  179. }
  180. powerwash() {
  181. echo "ARE YOU SURE YOU WANT TO POWERWASH??? THIS WILL REMOVE ALL USER ACCOUNTS"
  182. sleep 2
  183. echo "(press enter to continue, ctrl-c to cancel)"
  184. swallow_stdin
  185. read -r
  186. doas echo "fast safe" >/mnt/stateful_partition/factory_install_reset
  187. doas reboot
  188. exit
  189. }
  190. revert() {
  191. echo "This option will re-enroll your chromebook restore to before fakemurk was run. This is useful if you need to quickly go back to normal"
  192. echo "THIS IS A PERMANENT CHANGE!! YOU WILL NOT BE ABLE TO GO BACK UNLESS YOU UNENROLL AGAIN AND RUN THE SCRIPT, AND IF YOU UPDATE TO THE VERSION SH1MMER IS PATCHED, YOU MAY BE STUCK ENROLLED"
  193. echo "ARE YOU SURE YOU WANT TO CONTINUE? (press enter to continue, ctrl-c to cancel)"
  194. swallow_stdin
  195. read -r
  196. sleep 4
  197. echo "setting kernel priority"
  198. DST=/dev/$(get_largest_nvme_namespace)
  199. if doas "((\$(cgpt show -n \"$DST\" -i 2 -P) > \$(cgpt show -n \"$DST\" -i 4 -P)))"; then
  200. doas cgpt add "$DST" -i 2 -P 0
  201. doas cgpt add "$DST" -i 4 -P 1
  202. else
  203. doas cgpt add "$DST" -i 4 -P 0
  204. doas cgpt add "$DST" -i 2 -P 1
  205. fi
  206. echo "setting vpd"
  207. doas vpd -i RW_VPD -s check_enrollment=1
  208. doas vpd -i RW_VPD -s block_devmode=1
  209. doas crossystem.old block_devmode=1
  210. echo "Done. Press enter to reboot"
  211. swallow_stdin
  212. read -r
  213. echo "bye!"
  214. sleep 2
  215. doas reboot
  216. sleep 1000
  217. }
  218. harddisableext() { # calling it "hard disable" because it only reenables when you press
  219. echo "Please choose the extension you wish to disable."
  220. echo "(1) GoGuardian"
  221. echo "(2) Securly Filter"
  222. echo "(3) LightSpeed Filter"
  223. echo "(4) Cisco Umbrella"
  224. echo "(5) ContentKeeper Authenticator"
  225. echo "(6) Hapara"
  226. echo "(7) iboss"
  227. echo "(8) LightSpeed Classroom"
  228. echo "(9) Blocksi"
  229. echo "(10) Linewize"
  230. echo "(11) Securly Classroom"
  231. echo "(12) Impero"
  232. echo "(13) put extension ID in manually"
  233. read -r -p "> (1-13): " choice
  234. case "$choice" in
  235. 1) extid=haldlgldplgnggkjaafhelgiaglafanh;;
  236. 2) extid=iheobagjkfklnlikgihanlhcddjoihkg;;
  237. 3) extid=adkcpkpghahmbopkjchobieckeoaoeem;;
  238. 4) extid=jcdhmojfecjfmbdpchihbeilohgnbdci;;
  239. 5) extid=jdogphakondfdmcanpapfahkdomaicfa;;
  240. 6) extid=aceopacgaepdcelohobicpffbbejnfac;;
  241. 7) extid=kmffehbidlalibfeklaefnckpidbodff;;
  242. 8) extid=jaoebcikabjppaclpgbodmmnfjihdngk;;
  243. 9) extid=ghlpmldmjjhmdgmneoaibbegkjjbonbk;;
  244. 10) extid=ddfbkhpmcdbciejenfcolaaiebnjcbfc;;
  245. 11) extid=jfbecfmiegcjddenjhlbhlikcbfmnafd;;
  246. 12) extid=jjpmjccpemllnmgiaojaocgnakpmfgjg;;
  247. 13) read -r -p "enter extension id>" extid;;
  248. *) echo "invalid option" ;;
  249. esac
  250. chmod 000 "/home/chronos/user/Extensions/$extid"
  251. kill -9 $(pgrep -f "\-\-extension\-process")
  252. }
  253. hardenableext() {
  254. echo "Please choose the extension you wish to enable."
  255. echo "(1) GoGuardian"
  256. echo "(2) Securly Filter"
  257. echo "(3) LightSpeed Filter"
  258. echo "(4) Cisco Umbrella"
  259. echo "(5) ContentKeeper Authenticator"
  260. echo "(6) Hapara"
  261. echo "(7) iboss"
  262. echo "(8) LightSpeed Classroom"
  263. echo "(9) Blocksi"
  264. echo "(10) Linewize"
  265. echo "(11) Securly Classroom"
  266. echo "(12) Impero"
  267. echo "(13) put extension ID in manually"
  268. read -r -p "> (1-13): " choice
  269. case "$choice" in
  270. 1) extid=haldlgldplgnggkjaafhelgiaglafanh;;
  271. 2) extid=iheobagjkfklnlikgihanlhcddjoihkg;;
  272. 3) extid=adkcpkpghahmbopkjchobieckeoaoeem;;
  273. 4) extid=jcdhmojfecjfmbdpchihbeilohgnbdci;;
  274. 5) extid=jdogphakondfdmcanpapfahkdomaicfa;;
  275. 6) extid=aceopacgaepdcelohobicpffbbejnfac;;
  276. 7) extid=kmffehbidlalibfeklaefnckpidbodff;;
  277. 8) extid=jaoebcikabjppaclpgbodmmnfjihdngk;;
  278. 9) extid=ghlpmldmjjhmdgmneoaibbegkjjbonbk;;
  279. 10) extid=ddfbkhpmcdbciejenfcolaaiebnjcbfc;;
  280. 11) extid=jfbecfmiegcjddenjhlbhlikcbfmnafd;;
  281. 12) extid=jjpmjccpemllnmgiaojaocgnakpmfgjg;;
  282. 13) read -r -p "enter extension id>" extid;;
  283. *) echo "invalid option" ;;
  284. esac
  285. chmod 777 "/home/chronos/user/Extensions/$extid"
  286. kill -9 $(pgrep -f "\-\-extension\-process")
  287. }
  288. softdisableext() {
  289. echo "Extensions will stay disabled until you press Ctrl+c or close this tab"
  290. while true; do
  291. kill -9 $(pgrep -f "\-\-extension\-process") 2>/dev/null
  292. sleep 0.5
  293. done
  294. }
  295. install_crouton() {
  296. doas "bash <(curl -SLk https://goo.gl/fd3zc) -t xfce -r bullseye"
  297. touch /mnt/stateful_partition/crouton
  298. }
  299. start_crouton() {
  300. doas "startxfce4"
  301. }
  302. if [ "$0" = "$BASH_SOURCE" ]; then
  303. stty sane
  304. main
  305. fi