mush.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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 -d /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 release_board=$(lsbval CHROMEOS_RELEASE_BOARD)
  136. local board=${release_board%%-*}
  137. local hwid=$(jq "(.builds.$board[] | keys)[0]" <<<"$builds")
  138. local hwid=${hwid:1:-1}
  139. local latest_milestone=$(jq "(.builds.$board[].$hwid.pushRecoveries | keys) | .[length - 1]" <<<"$builds")
  140. local remote_version=$(jq ".builds.$board[].$hwid[$latest_milestone].version" <<<"$builds")
  141. local remote_version=${remote_version:1:-1}
  142. local local_version=$(lsbval GOOGLE_RELEASE)
  143. if (( ${remote_version%%\.*} > ${local_version%%\.*} )); then
  144. 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"
  145. read -r
  146. sleep 4
  147. # read choice
  148. local reco_dl=$(jq ".builds.$board[].$hwid.pushRecoveries[$latest_milestone]" <<< "$builds")
  149. local tmpdir=/mnt/stateful_partition/update_tmp/
  150. doas mkdir $tmpdir
  151. echo "downloading ${remote_version} from ${reco_dl}"
  152. curl "${reco_dl:1:-1}" | doas "dd of=$tmpdir/image.zip status=progress"
  153. echo "unzipping update binary"
  154. cat $tmpdir/image.zip | gunzip | doas "dd of=$tmpdir/image.bin status=progress"
  155. doas rm -f $tmpdir/image.zip
  156. echo "invoking image patcher"
  157. doas image_patcher.sh "$tmpdir/image.bin"
  158. local loop=$(doas losetup -f | tr -d '\r')
  159. doas losetup -P "$loop" "$tmpdir/image.bin"
  160. echo "performing update"
  161. local dst=/dev/$(get_largest_nvme_namespace)
  162. local tgt_kern=$(opposite_num $(get_booted_kernnum))
  163. local tgt_root=$(( $tgt_kern + 1 ))
  164. local kerndev=${dst}p${tgt_kern}
  165. local rootdev=${dst}p${tgt_root}
  166. echo "installing kernel patch to ${kerndev}"
  167. doas dd if="${loop}p4" of="$kerndev" status=progress
  168. echo "installing root patch to ${rootdev}"
  169. doas dd if="${loop}p3" of="$rootdev" status=progress
  170. echo "setting kernel priority"
  171. doas cgpt add "$dst" -i 4 -P 0
  172. doas cgpt add "$dst" -i 2 -P 0
  173. doas cgpt add "$dst" -i "$tgt_kern" -P 1
  174. doas crossystem.old block_devmode=0
  175. doas vpd -i RW_VPD -s block_devmode=0
  176. # doas rm -rf $tmpdir
  177. else
  178. echo "update not required"
  179. fi
  180. }
  181. powerwash() {
  182. echo "ARE YOU SURE YOU WANT TO POWERWASH??? THIS WILL REMOVE ALL USER ACCOUNTS"
  183. sleep 2
  184. echo "(press enter to continue, ctrl-c to cancel)"
  185. swallow_stdin
  186. read -r
  187. doas rm -f /stateful_unfucked
  188. doas reboot
  189. exit
  190. }
  191. revert() {
  192. 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"
  193. 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"
  194. echo "ARE YOU SURE YOU WANT TO CONTINUE? (press enter to continue, ctrl-c to cancel)"
  195. swallow_stdin
  196. read -r
  197. sleep 4
  198. echo "setting kernel priority"
  199. DST=/dev/$(get_largest_nvme_namespace)
  200. if doas "((\$(cgpt show -n \"$DST\" -i 2 -P) > \$(cgpt show -n \"$DST\" -i 4 -P)))"; then
  201. doas cgpt add "$DST" -i 2 -P 0
  202. doas cgpt add "$DST" -i 4 -P 1
  203. else
  204. doas cgpt add "$DST" -i 4 -P 0
  205. doas cgpt add "$DST" -i 2 -P 1
  206. fi
  207. echo "setting vpd"
  208. doas vpd -i RW_VPD -s check_enrollment=1
  209. doas vpd -i RW_VPD -s block_devmode=1
  210. doas crossystem.old block_devmode=1
  211. rm -f /stateful_unfucked
  212. echo "Done. Press enter to reboot"
  213. swallow_stdin
  214. read -r
  215. echo "bye!"
  216. sleep 2
  217. doas reboot
  218. sleep 1000
  219. }
  220. harddisableext() { # calling it "hard disable" because it only reenables when you press
  221. echo "Please choose the extension you wish to disable."
  222. echo "(1) GoGuardian"
  223. echo "(2) Securly Filter"
  224. echo "(3) LightSpeed Filter"
  225. echo "(4) Cisco Umbrella"
  226. echo "(5) ContentKeeper Authenticator"
  227. echo "(6) Hapara"
  228. echo "(7) iboss"
  229. echo "(8) LightSpeed Classroom"
  230. echo "(9) Blocksi"
  231. echo "(10) Linewize"
  232. echo "(11) Securly Classroom"
  233. echo "(12) Impero"
  234. echo "(13) put extension ID in manually"
  235. read -r -p "> (1-13): " choice
  236. case "$choice" in
  237. 1) extid=haldlgldplgnggkjaafhelgiaglafanh;;
  238. 2) extid=iheobagjkfklnlikgihanlhcddjoihkg;;
  239. 3) extid=adkcpkpghahmbopkjchobieckeoaoeem;;
  240. 4) extid=jcdhmojfecjfmbdpchihbeilohgnbdci;;
  241. 5) extid=jdogphakondfdmcanpapfahkdomaicfa;;
  242. 6) extid=aceopacgaepdcelohobicpffbbejnfac;;
  243. 7) extid=kmffehbidlalibfeklaefnckpidbodff;;
  244. 8) extid=jaoebcikabjppaclpgbodmmnfjihdngk;;
  245. 9) extid=ghlpmldmjjhmdgmneoaibbegkjjbonbk;;
  246. 10) extid=ddfbkhpmcdbciejenfcolaaiebnjcbfc;;
  247. 11) extid=jfbecfmiegcjddenjhlbhlikcbfmnafd;;
  248. 12) extid=jjpmjccpemllnmgiaojaocgnakpmfgjg;;
  249. 13) read -r -p "enter extension id>" extid;;
  250. *) echo "invalid option" ;;
  251. esac
  252. echo "$extid" | grep -qE '^[a-z]{32}$' && chmod 000 "/home/chronos/user/Extensions/$extid" && kill -9 $(pgrep -f "\-\-extension\-process") || "invalid input"
  253. }
  254. hardenableext() {
  255. echo "Please choose the extension you wish to enable."
  256. echo "(1) GoGuardian"
  257. echo "(2) Securly Filter"
  258. echo "(3) LightSpeed Filter"
  259. echo "(4) Cisco Umbrella"
  260. echo "(5) ContentKeeper Authenticator"
  261. echo "(6) Hapara"
  262. echo "(7) iboss"
  263. echo "(8) LightSpeed Classroom"
  264. echo "(9) Blocksi"
  265. echo "(10) Linewize"
  266. echo "(11) Securly Classroom"
  267. echo "(12) Impero"
  268. echo "(13) put extension ID in manually"
  269. read -r -p "> (1-13): " choice
  270. case "$choice" in
  271. 1) extid=haldlgldplgnggkjaafhelgiaglafanh;;
  272. 2) extid=iheobagjkfklnlikgihanlhcddjoihkg;;
  273. 3) extid=adkcpkpghahmbopkjchobieckeoaoeem;;
  274. 4) extid=jcdhmojfecjfmbdpchihbeilohgnbdci;;
  275. 5) extid=jdogphakondfdmcanpapfahkdomaicfa;;
  276. 6) extid=aceopacgaepdcelohobicpffbbejnfac;;
  277. 7) extid=kmffehbidlalibfeklaefnckpidbodff;;
  278. 8) extid=jaoebcikabjppaclpgbodmmnfjihdngk;;
  279. 9) extid=ghlpmldmjjhmdgmneoaibbegkjjbonbk;;
  280. 10) extid=ddfbkhpmcdbciejenfcolaaiebnjcbfc;;
  281. 11) extid=jfbecfmiegcjddenjhlbhlikcbfmnafd;;
  282. 12) extid=jjpmjccpemllnmgiaojaocgnakpmfgjg;;
  283. 13) read -r -p "enter extension id>" extid;;
  284. *) echo "invalid option" ;;
  285. esac
  286. echo "$extid" | grep -qE '^[a-z]{32}$' && chmod 777 "/home/chronos/user/Extensions/$extid" && kill -9 $(pgrep -f "\-\-extension\-process") || "invalid input"
  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