Monday, July 30, 2012

Command ေတြကို Bash History ကေဖ်ာက္ရေအာင္




Bash မွာ ေရွ႕က႐ိုက္သြားတဲ့ history ကိုသိမ္းထားပါတယ္။ ျပန္ၾကည့္ခ်င္ရင္ 'history' ဆိုတဲ့ command နဲ႕ ျပန္ေခၚၾကည့္လို႕ရပါတယ္။ System administrator ေတြ ၊ system engineer ေတြ တစ္ခုခုေမ့သြားရင္ ျပန္ၾကည့္ဖို႕လည္း လြယ္သလို၊ Team လိုက္ဆိုရင္ သူမ်ားဘာလုပ္ထားလည္းျပန္ၾကည့္လို႕ ရတယ္။

တစ္ခါတစ္ေလ ကိုယ္႐ိုက္ထားတဲ့ command ကို သူမ်ားကိုမၾကည့္ေစခ်င္ဘူး။ 'root' ေပးမသုံးတဲ့ locked down system မွာဆိုရင္ ကိုယ့္ bash history နဲ႕ကိုယ္ရွိေပမဲ့ 'root' ကို share ျပီးသုံးၾကရင္ bash history ကတစ္ခုထဲ။ကိုယ္ဘာလုပ္သြားလည္း ေနာက္လူက history မွာျပန္ၾကည့္လို႕ရတယ္ ။ တစ္ခါတစ္ေလ ကိုယ္ troubleshoot လုပ္ထားပံုကို ေနာက္လူကို မသိေစခ်င္ရင္ ဘယ္လိုလုပ္မလည္း ? ( Team ေတြ Department ေတြ ကြဲတဲ့ Company ေတြမွာ အခ်င္းခ်င္းျပိဳင္ဆိုင္မႈေတြ ရွိပါတယ္။ ဟိုဘက္ Team ကေကာင္ေတြ စသုံးမက်ဘူးလို႕ ေျပာဖို႕ ေစာင့္ေနၾကေတာ့ ကိုယ့္အလွည့္က်ရင္လည္း ကိုယ့္ knowledge ကို တျခား team ကိုမေပးခ်င္တာေတြ ရွိတတ္ပါတယ္။)

တစ္ခါတစ္ေလၾက audit ေပါ့။ Server မွာ ျပသနာ တစ္ခုခုျဖစ္သြားရင္ ၊ ဘယ္သူ႕ေၾကာင့္လည္း ျပန္ရွာတယ္။ ကိုယ္ကအမွားလုပ္လိုက္မိလို႕ ျပန္ fix လုပ္ျပီး ဖုံးထားခ်င္ရင္ေတာင္ bash history ကလိမ္ဖို႕ ခက္တယ္။bash_history file ကို edit လုပ္ရင္လည္း file integrity ပ်က္တယ္။ ေနာက္ျပီး edit လုပ္ထားမွန္းက ေဖ်ာက္ဖို႕မလြယ္ ။

ကဲ ကိုယ္႐ိုက္ထားတဲ့ command ေတြ ဘယ္လို ေဖ်ာက္ထားမလည္း ?

'history' command ရဲ့ output ကိုတစ္ခ်က္ၾကည့္ရေအာင္ ။

  994  exit
  995  cd /etc
  996  ls
  997  ls
  998  vi rc.local
  999  ps -ef|more
 1000  exit

ဒီမွာ ဘယ္ဘက္က နံပါတ္ေတြကို offset လို႕ေခၚပါတယ္။ ညာဘက္ျခမ္းကေတာ့ command ေပါ့။ Offset number ကိုသိရင္ အဲ offset number ကို bash history ကေနဖ်က္ဖို႕ command ရွိပါတယ္။

'history' command မွာ '-d' ဆိုတဲ့ option ရွိပါတယ္ ။ ကိုယ္ဖ်က္ခ်င္တဲ့ command ကို history ကဖ်က္လို႕ရပါတယ္။ တစ္ခုပဲ ျပသနာက ။ 'history -d xx' ဆိုတဲ့ ဖ်က္လိုက္တယ္ဆိုတဲ့ line ၾကီးကေတာ့  history ထဲဝင္သြားတယ္။ ဥပမာ offset number 998 ( vi rc.local) ဆိုတာကို history ကဖ်က္ခ်င္တယ္ဆိုရင္ ' history -d 998' လို႕ ဖ်က္ရပါတယ္ ။ ဒါေပမဲ့ ေနာက္တစ္ခါ history ျပန္ၾကည့္ရင္ ဒီလိုၾကီး  ေပၚလိမ့္မယ္။

  994  exit
  995  cd /etc
  996  ls
  997  ls
  998 ps -ef|more
  999  exit
 1000  history -d 998

အဲေတာ့မွ ဘာဖ်က္ထားတာလည္းဆိုျပီး ရွုပ္ကုန္မွာ။ နည္းနည္း ပိုေကာင္းတဲ့ နည္းလမ္းေတြရွိပါတယ္ ။

Bash မွာ Shell Variable တစ္ခုရွိပါတယ္။ HISTCMD လို႕ေခၚတဲ့ Variable ပါ။ 'echo $HISTCMD' လို႕႐ိုက္ၾကည့္ရင္ နံပါတ္တစ္ခုကိုေပးပါလိမ့္မယ္။ အဲဒါက ေနာက္ command အတြက္ offset ပါ။ ခုနက 1000 အထိေရာက္ျပီးတဲ့ အခ်ိန္မွာ  'echo $HISTCMD' လို႕႐ိုက္ၾကည့္ရင္ 1002 ဆိုတဲ့ output ကိုေပးပါလိမ့္မယ္။ ဘာလို႕လည္းဆို 1000 က 'history -d 998' ဆိုတဲ့ command ျဖစ္ျပီး echo $HISTCMD က 1001 ပါ။ အဲေတာ့ output က ေနာက္ command အတြက္ ရမယ့္ offset 1002 လို႕ရတာပါ။ ဒီ Variable ကိုသုံးျပီး bash history ကိုလိမ္လို႕ရပါတယ္။

$HISTCMD က ေနာက္လာမဲ့ command ရဲ့ offset ကိုေပးတယ္လို႕ ခုနကေျပာထားတယ္ေနာ္။ $HISTCMD-1 ဆိုရင္ လက္ရွိ command ရဲ့ offset ေပါ့။ 'history -d (($HISTCMD-1)) ဆိုရင္ ဒီ command ကို bash history ကေန ျပန္ျပန္ဖ်က္ေနတာနဲ႕ အတူတူပဲ။

ေနာက္တစ္ခု သိရမွာက Bash ရဲ့ operator ေတြပါ ။ Bash ရဲ့ '&&' ဆိုတဲ့ operator က 'AND' ကို ကိုယ္စားျပဳပါတယ္။ Command ႏွစ္ခုကို တစ္ခုျပီး တစ္ခု ဆက္လုပ္သြားဖို႕ သုံးပါတယ္။ Package compilation အတြက္ 'make && make install' ဆိုတာမ်ိဳး႐ိုက္ျပီး ထမင္းသြားစာတာမ်ိဳးေပါ့။ ပထမ command က completed successful ျဖစ္ရင္ ဒုတိရ command ကို ဆက္အလုပ္လုပ္ပါတယ္။ Error ျဖစ္သြားရင္ေတာ့ ရပ္သြားတယ္။ Command ႏွစ္ခုျဖစ္ေပမဲ့ Bash History မွာေတာ့ offset တစ္ခုနဲ႕ entry တစ္ခုပဲ ဝင္ပါတယ္။

1003  ls -l && history

ကဲ ဒီေလာက္ဆို မွန္းမိေလာက္ပါျပီ ။ ႐ိုက္ခ်င္တဲ့ command ကို႐ိုက္ ၊ ျပီးရင္ေနာက္က && ခံျပီး 'history -d (($HISTCMD-1))' ထဲ့႐ိုက္ရင္ ကိုယ္႐ိုက္သမွ် bash history ထဲ မေရာက္ေတာ့ဘူး။ ဒါမ်ိဳးေပါ့ ..

# rm -rf /etc && history -d (($HISTCMD-1))

ဒါဆို /etc ကို ဖ်က္လိုက္တဲ့ command က history ထဲမေရာက္ေတာ့ဘူး။ 'history -d' ကို အေရွ႕မွာထားထား အေနာက္မွာထားထား တူတူပါပဲ။ တစ္ခါတစ္ေလ ေနာက္က ထဲ့႐ိုက္ဖို႕ေမ့သြားရင္လို႕ bash history ထဲေရာက္သြားရင္ေတာ့  ဒီလို ကြန္႕လိုက္ေပါ့။ ဒါဆို ေနာက္ဆုံး history ႏွစ္ခု ဖ်က္သြားလိမ့္မယ္။ ေရွ႕က ေမ့သြားတဲ့ command ေရာ ၊ ဒီဖ်က္တဲ့ဟာကိုေရာ။

# history -d $((HISTCMD-2)) && history -d $((HISTCMD-1))

Catch တစ္ခုေတာ့ ရွိပါတယ္။ ဒါက Bash Variable ပါ ။ ဒါေတာင္ Bash version အေဟာင္းေတြမွာ ဒီ Variable မရွိပါဘူး။ ksh တို႕ဘာတို႕မွာလည္း မရွိဘူး ထင္တယ္။  HISTCMD မရွိရင္ နည္းနည္း ေလး အလုပ္ပိုပါတယ္။

TMP=$(history | tail -1 | awk '{print $1}') && history -d $TMP

ဒါလည္း ေရွ႕ကထားထား ေနာက္ကထားထား ရပါတယ္ ။

႐ိုက္ရတာ ရွုပ္ရင္ ကိုယ့္ bashrc ထဲမွာ ကိုယ့္ဟာကို alias ေပးထားလိုက္ေပါ့ ။ ဒါေပမယ့္ trace မက်န္ေအာင္ဖ်က္ပါတယ္ဆို bashrc မွာ trace ၾကီးက်န္ေနမွာေတာ့ မမိုက္ပါဘူး ၊ ဒါေပမဲ့ က်ေနာ္လို lazy ေတြကေတာ့ ဝင္ဝင္ခ်င္း alias ေလးေပး ၊ ျပီး session close မလုပ္ခင္မွာ bashrc ကေန ျပန္ဖ်က္ျပီး အေပၚမွာေပးထားတဲ့အတိုင္း ေနာက္ဆုံး command ႏွစ္ခုဖ်က္ခဲ့လိုက္တယ္။

တစ္ခုေတာ့ Caution ေပးပါတယ္။ တစ္ခ်ိဳ႕ environment မွာ VPN နဲ႕မွ servers ေတြကို ဝင္လို႕ရျပီး VPN မွာ keystroke log လုပ္ထားတတ္ပါတယ္။ ဒါဆိုရင္ေတာ့ ဟဲဟဲ ။
ကဲ ကိုယ့္ trace ကိုယ္ ေဖ်ာက္ႏိုင္ပါေစ ။ က်ေနာ္ သိတဲ့ ၊ သုံးတဲ့ technique တစ္ခုကို share တာပါ ။ က်ေနာ္မသိတဲ့ catch ရွိေကာင္းရွိႏိုင္ပါတယ္ ။

Divinity